diff --git a/authservice/src/views.py b/authservice/src/views.py index 88edb97..1d9bf6e 100644 --- a/authservice/src/views.py +++ b/authservice/src/views.py @@ -14,7 +14,7 @@ def generate_access_token(user_id, jti): payload = { 'user_id': user_id, 'jti': jti, # unique identifier for the token pair. - 'exp': datetime.now(tz=timezone.utc) + timedelta(minutes=45), + 'exp': datetime.now(tz=timezone.utc) + timedelta(seconds=5), 'iat': datetime.now(tz=timezone.utc) } access_token = jwt.encode(payload, settings.SECRET_KEY, algorithm='HS256') diff --git a/bucketservice/media/images/avatar7_1ERBFAb.png b/bucketservice/media/images/avatar7_1ERBFAb.png new file mode 100644 index 0000000..90b1019 Binary files /dev/null and b/bucketservice/media/images/avatar7_1ERBFAb.png differ diff --git a/frontend/src/routes/ai/Ai.js b/frontend/src/routes/ai/Ai.js index add276c..e00332b 100644 --- a/frontend/src/routes/ai/Ai.js +++ b/frontend/src/routes/ai/Ai.js @@ -1,73 +1,61 @@ -import { navigateTo } from "../../utils/navTo.js"; +import { navigateTo as originalNavigateTo } from "../../utils/navTo.js"; export async function fetchAi() { - if (!localStorage.getItem("access_token")) { + const access_token = localStorage.getItem("access_token"); + if (!access_token) { + console.log("No access token found"); navigateTo("/login"); } else { const canvas = document.getElementById('gameCanvas'); const ctx = canvas.getContext('2d'); const scoreBoard = document.getElementById('scoreBoard'); const startButton = document.getElementById('startButton'); - const paddleHeight = 100; const paddleWidth = 10; const ballSize = 10; - let leftPaddleY = canvas.height / 2 - paddleHeight / 2; let rightPaddleY = canvas.height / 2 - paddleHeight / 2; let ballX = canvas.width / 2; let ballY = canvas.height / 2; let ballSpeedX = 5; let ballSpeedY = 5; - let leftScore = 0; let rightScore = 0; - let gameRunning = false; - function drawRect(x, y, width, height, color) { ctx.fillStyle = color; ctx.fillRect(x, y, width, height); } - function drawCircle(x, y, radius, color) { ctx.fillStyle = color; ctx.beginPath(); ctx.arc(x, y, radius, 0, Math.PI * 2, false); ctx.fill(); } - function drawNet() { for (let i = 0; i < canvas.height; i += 40) { drawRect(canvas.width / 2 - 1, i, 2, 20, '#fff'); } } - function draw() { // Clear canvas drawRect(0, 0, canvas.width, canvas.height, '#000'); - // Draw paddles drawRect(0, leftPaddleY, paddleWidth, paddleHeight, '#fff'); drawRect(canvas.width - paddleWidth, rightPaddleY, paddleWidth, paddleHeight, '#fff'); - // Draw ball drawCircle(ballX, ballY, ballSize, '#fff'); - // Draw net drawNet(); } - function update() { // Move ball ballX += ballSpeedX; ballY += ballSpeedY; - // Ball collision with top and bottom walls if (ballY - ballSize < 0 || ballY + ballSize > canvas.height) { ballSpeedY = -ballSpeedY * 1.05; } - // Ball collision with paddles if ( (ballX - ballSize < paddleWidth && ballY > leftPaddleY && ballY < leftPaddleY + paddleHeight) || @@ -75,7 +63,6 @@ export async function fetchAi() { ) { ballSpeedX = -ballSpeedX * 1.05; } - // Score points if (ballX < 0) { rightScore++; @@ -84,10 +71,8 @@ export async function fetchAi() { leftScore++; resetBall(); } - // Update score display scoreBoard.textContent = `Player 1: ${leftScore} | AI: ${rightScore}`; - // Check for game over if (leftScore === 5 || rightScore === 5) { const winner = leftScore === 5 ? "Player 1" : "AI"; @@ -99,15 +84,12 @@ export async function fetchAi() { navigateTo("/ai"); } } - function resetBall() { ballX = canvas.width / 2; ballY = canvas.height / 2; ballSpeedX = -ballSpeedX; ballSpeedY = Math.random() > 0.5 ? 5 : -5; } - - function gameLoop() { if (gameRunning) { handleInput(); @@ -116,18 +98,14 @@ export async function fetchAi() { requestAnimationFrame(gameLoop); } } - // Keyboard controls const keys = {}; - document.addEventListener('keydown', (e) => { keys[e.key] = true; }); - document.addEventListener('keyup', (e) => { keys[e.key] = false; }); - function handleInput() { // Left paddle if (keys['w'] && leftPaddleY > 0) { @@ -136,7 +114,6 @@ export async function fetchAi() { if (keys['s'] && leftPaddleY < canvas.height - paddleHeight) { leftPaddleY += 5; } - // AI controlled right paddle const aiSpeed = 5 + Math.random() * 2; // AI speed varies between 3 and 5 if (rightPaddleY + paddleHeight / 2 < ballY) { @@ -144,7 +121,6 @@ export async function fetchAi() { } else if (rightPaddleY + paddleHeight / 2 > ballY) { rightPaddleY -= aiSpeed; } - // Ensure AI paddle stays within canvas bounds if (rightPaddleY < 0) { rightPaddleY = 0; @@ -152,7 +128,6 @@ export async function fetchAi() { rightPaddleY = canvas.height - paddleHeight; } } - startButton.addEventListener('click', () => { if (!gameRunning) { gameRunning = true; @@ -164,45 +139,37 @@ export async function fetchAi() { gameLoop(); } }); - function finishGame() { gameRunning = false; startButton.style.display = 'block'; alert("VS AI is aborted!"); } - // Listen for navigation events const originalPushState = history.pushState; const originalReplaceState = history.replaceState; - history.pushState = function () { if (gameRunning) { finishGame(); } return originalPushState.apply(history, arguments); }; - history.replaceState = function () { if (gameRunning) { finishGame(); } return originalReplaceState.apply(history, arguments); }; - window.addEventListener('popstate', () => { if (gameRunning) { finishGame(); } }); - function navigateTo(url) { if (gameRunning) { finishGame(); } originalNavigateTo(url); } - draw(); } } - diff --git a/frontend/src/routes/changepassword/Changepassword.js b/frontend/src/routes/changepassword/Changepassword.js index a0d75ac..bb5bde2 100644 --- a/frontend/src/routes/changepassword/Changepassword.js +++ b/frontend/src/routes/changepassword/Changepassword.js @@ -50,6 +50,8 @@ export async function fetchChangepassword() { return RefreshToken().then(() => { return postChangePasswordRequest().then(handleResponse); }); + } else if (response.status === 401 && errorData.error) { + document.getElementById("logout-button").click(); } else { throw errorData; } @@ -61,6 +63,10 @@ export async function fetchChangepassword() { postChangePasswordRequest() .then(handleResponse) .then(data => { + if (data.error) { + insertIntoElement('fields-warning', "Error: " + data.error); + return; + } setTimeout(() => { alert("Password changed successfully"); navigateTo("/"); diff --git a/frontend/src/routes/edit/Edit.js b/frontend/src/routes/edit/Edit.js index 5e3a327..4e25f62 100644 --- a/frontend/src/routes/edit/Edit.js +++ b/frontend/src/routes/edit/Edit.js @@ -19,6 +19,20 @@ export async function fetchEdit() { if (!response.ok) { const errorData = await response.json(); + if (response.status === 401) { + if (errorData.error === "Token has expired") { + await RefreshToken(); + return fetchEdit(); + } + document.getElementById("logout-button").click(); + return; + } + if (response.status === 500) { + let message = "error: " + errorData.error; + alert(message); + navigateTo("/"); // redirect to home page + return; + } throw new Error(errorData.error); } @@ -62,16 +76,21 @@ export async function fetchEdit() { const handleResponse = response => { if (!response.ok) { return response.json().then(errorData => { - if (response.status === 401 && errorData.error === "Token has expired") { - return RefreshToken().then(() => { - return postUpdateUserRequest().then(handleResponse); - }); + if (response.status === 401) { + if (errorData.error === "Token has expired") { + return RefreshToken().then(() => { + return postUpdateUserRequest().then(handleResponse); + }); + } + document.getElementById("logout-button").click(); + return; } else if (response.status === 207) { alert("Email updated successfully, please verify your email"); document.getElementById("logout-button").click(); return; - } - else { + } else if (response.status === 500) { + throw errorData; + } else { throw errorData; } }); @@ -81,9 +100,12 @@ export async function fetchEdit() { postUpdateUserRequest() .then(handleResponse) - .then(() => { - alert("Profile updated successfully"); - navigateTo("/profile"); + .then((data) => { + if (!data.error) { + alert("Profile updated successfully"); + navigateTo("/profile"); + return; + } }) .catch(err => { if (err.error) { @@ -133,12 +155,16 @@ export async function fetchEdit() { const handleResponse = response => { if (!response.ok) { return response.json().then(errorData => { - if (response.status === 401 && errorData.error === "Token has expired") { - return RefreshToken().then(() => { - return postAvatarUpdate().then(handleResponse); - }); + if (response.status === 401) { + if (errorData.error === "Token has expired") { + return RefreshToken().then(() => { + return postAvatarUpdate().then(handleResponse); + }); + } + document.getElementById("logout-button").click(); + return; } else { - throw new Error("Couldn't update avatar"); + throw errorData; } }); } @@ -147,11 +173,15 @@ export async function fetchEdit() { postAvatarUpdate() .then(handleResponse) .then(data => { - alert("Avatar updated successfully"); - navigateTo("/profile"); + if (!data.error) { + alert("Avatar updated successfully"); + navigateTo("/profile"); + } }) .catch(error => { - console.error(error); + if (error.error) { + insertIntoElement('fields-warning', "Error: " + error.error); + } }); }); diff --git a/frontend/src/routes/friendrequests/Friendrequests.js b/frontend/src/routes/friendrequests/Friendrequests.js index 9242f71..60a91d6 100644 --- a/frontend/src/routes/friendrequests/Friendrequests.js +++ b/frontend/src/routes/friendrequests/Friendrequests.js @@ -20,16 +20,26 @@ export async function fetchFriendrequests() { }); if (!response_user.ok) { const errorData = await response_user.json(); - if (errorData.error === 'Token has expired') { - await RefreshToken(); - return fetchFriendrequests(); // Retry fetching after token refresh - } else { - throw new Error(errorData.error); + if (response_user.status === 401) { + if (errorData.error === "Token has expired") { + await RefreshToken(); + return fetchFriendrequests(); + } + document.getElementById("logout-button").click(); + return; + } + if (response_user.status === 500) { + let message = "error: " + errorData.error; + alert(message); + navigateTo("/"); // redirect to home page + return; } + throw new Error(errorData.error); } const data = await response_user.json(); const user = data.data[0]; + const response = await fetch(requestsList + "?page=" + currentPage + "&limit=5", { method: "GET", headers: { @@ -39,14 +49,20 @@ export async function fetchFriendrequests() { }); if (!response.ok) { const errorData = await response.json(); - if (errorData.error === 'Token has expired') { - await RefreshToken(); - return fetchFriendrequests(); // Retry fetching after token refresh + if (response.status === 401) { + if (errorData.error === "Token has expired") { + await RefreshToken(); + return fetchFriendrequests(); + } + document.getElementById("logout-button").click(); + return; } else { throw new Error(errorData.error); } } + + const requests_res = await response.json(); const requests = requests_res.data; let paginate_data = requests_res.pagination; diff --git a/frontend/src/routes/friends/Friends.js b/frontend/src/routes/friends/Friends.js index 69c503b..a232660 100644 --- a/frontend/src/routes/friends/Friends.js +++ b/frontend/src/routes/friends/Friends.js @@ -7,7 +7,6 @@ let total_pages = 1; export async function fetchFriends() { if (!localStorage.getItem("access_token")) { - navigateTo("/login"); return; } @@ -23,9 +22,13 @@ export async function fetchFriends() { if (!response.ok) { const errorData = await response.json(); - if (errorData.error === 'Token has expired') { - await RefreshToken(); - return fetchFriends(); // Retry fetching after token refresh + if (response.status === 401) { + if (errorData.error === 'Token has expired') { + await RefreshToken(); + return fetchFriends(); // Retry fetching after token refresh + } + document.getElementById("logout-button").click(); + return; } else { throw new Error(errorData.error); } @@ -51,7 +54,13 @@ export async function fetchFriends() { } }).then(response => { if (!response.ok) { - throw new Error("Failed to fetch user details"); + if (response.status === 401) { + if (errorData.error === 'Token has expired') { + throw new Error('Token has expired'); + } + throw new Error('Unauthorized'); + } + throw new Error('Failed to fetch user details'); } return response.json(); }).then(data => { @@ -98,11 +107,13 @@ export async function fetchFriends() { }).catch((error) => { console.error(error); if (error.message === 'Token has expired') { - RefreshToken().then(() => { - fetchFriends(); - }); + return fetchFriends(); // Retry fetching after token refresh + } else if (error.message === 'Unauthorized') { + document.getElementById("logout-button").click(); + return; } else { alert(error.message); + return; } }); }); @@ -138,14 +149,17 @@ async function deleteUser(userId) { if (!response.ok) { const errorData = await response.json(); - if (errorData.error === 'Token has expired') { - await RefreshToken(); - return deleteUser(userId); // Retry deleting after token refresh + if (response.status === 401) { + if (errorData.error === 'Token has expired') { + await RefreshToken(); + return deleteUser(userId); // Retry deleting after token refresh + } + document.getElementById("logout-button").click(); + return; } else { throw new Error(errorData.error); } } - await response.json(); navigateTo("/friends"); } catch (error) { @@ -153,8 +167,3 @@ async function deleteUser(userId) { alert(error.message); } } - - - - - diff --git a/frontend/src/routes/game/Game.js b/frontend/src/routes/game/Game.js index 4c5a6cc..7e9c959 100644 --- a/frontend/src/routes/game/Game.js +++ b/frontend/src/routes/game/Game.js @@ -18,11 +18,23 @@ export async function fetchGame() { }); if (!response.ok) { const errorData = await response.json(); + if (response.status === 401) { + if (errorData.error === "Token has expired") { + await RefreshToken(); + return fetchGame(); + } + document.getElementById("logout-button").click(); + return; + } + if (response.status === 500) { + let message = "error: " + errorData.error; + alert(message); + navigateTo("/"); + return; + } throw new Error(errorData.error); } - const data = await response.json(); - const user = data[0]; if (!game_id) { diff --git a/frontend/src/routes/join/Join.js b/frontend/src/routes/join/Join.js index 525134b..5bf1e24 100644 --- a/frontend/src/routes/join/Join.js +++ b/frontend/src/routes/join/Join.js @@ -22,12 +22,15 @@ export async function fetchJoin() { if (!response.ok) { const errorData = await response.json(); - if (errorData.error === 'Token has expired') { - await RefreshToken(); - return fetchJoin(); // Retry fetching invites after token refresh - } else { - throw new Error(errorData.error); + if (response.status === 401) { + if (errorData.error === 'Token has expired') { + await RefreshToken(); + return fetchJoin(); // Retry fetching invites after token refresh + } + document.getElementById("logout-button").click(); + return; } + throw new Error(errorData.error); } const invites_res = await response.json(); @@ -80,24 +83,28 @@ export async function fetchJoin() { const handleResponse = response => { if (!response.ok) { return response.json().then(data => { - if (response.status === 401 && data.error === "Token has expired") { - return RefreshToken().then(() => { - return postJoinRequest().then(handleResponse); - }); - } else { - throw new Error(data.error); + if (response.status === 401) { + if (data.error === 'Token has expired') { + return RefreshToken().then(() => { + return postJoinRequest().then(handleResponse); + }); + } + document.getElementById("logout-button").click(); + return; } + throw new Error(data.error); }); } return response.json(); }; - postJoinRequest() .then(handleResponse) - .then(data => { - alert("Joined game successfully"); - localStorage.setItem("game_id", data.data.game_id); - navigateTo("/game"); + .then((data) => { + if (!data.error) { + alert("Joined game successfully"); + localStorage.setItem("game_id", data.data.game_id); + navigateTo("/game"); + } }) .catch(error => { alert(error.message); diff --git a/frontend/src/routes/localgame/Localgame.js b/frontend/src/routes/localgame/Localgame.js index 28cb7ab..a61d2bb 100644 --- a/frontend/src/routes/localgame/Localgame.js +++ b/frontend/src/routes/localgame/Localgame.js @@ -1,17 +1,9 @@ import { navigateTo as originalNavigateTo } from "../../utils/navTo.js"; -// Override navigateTo function to detect navigation changes -function navigateTo(url) { - if (gameRunning) { - finishGame(); - } - originalNavigateTo(url); -} - export async function fetchLocalgame() { const access_token = localStorage.getItem("access_token"); if (!access_token) { - + console.log("No access token found"); navigateTo("/login"); } else { const canvas = document.getElementById('gameCanvas'); @@ -197,6 +189,14 @@ export async function fetchLocalgame() { } }); + // Override navigateTo function to detect navigation changes + function navigateTo(url) { + if (gameRunning) { + finishGame(); + } + originalNavigateTo(url); + } + draw(); } } diff --git a/frontend/src/routes/otherprofile/Otherprofile.js b/frontend/src/routes/otherprofile/Otherprofile.js index 41a0de9..f1a8016 100644 --- a/frontend/src/routes/otherprofile/Otherprofile.js +++ b/frontend/src/routes/otherprofile/Otherprofile.js @@ -25,12 +25,15 @@ export async function fetchOtherprofile() { }); if (!response.ok) { const errorData = await response.json(); - if (errorData.error === 'Token has expired') { - await RefreshToken(); - return fetchUserDetails(); // Retry fetching user details after token refresh - } else { - throw new Error(errorData.error); + if (response.status === 401) { + if (errorData.error === 'Token has expired') { + await RefreshToken(); + return fetchUserDetails(); // Retry fetching user details after token refresh + } + document.getElementById("logout-button").click(); + return; } + throw new Error(errorData.error); } return response.json(); }; @@ -58,12 +61,15 @@ export async function fetchOtherprofile() { }); if (!response.ok) { const errorData = await response.json(); - if (errorData.error === 'Token has expired') { - await RefreshToken(); - return fetchMatchHistory(); - } else { - throw new Error(errorData.error); + if (response.status === 401) { + if (errorData.error === 'Token has expired') { + await RefreshToken(); + return fetchMatchHistory(); + } + document.getElementById("logout-button").click(); + return; } + throw new Error(errorData.error); } return response.json(); }; diff --git a/frontend/src/routes/profile/Profile.js b/frontend/src/routes/profile/Profile.js index c020fd1..ee38dbf 100644 --- a/frontend/src/routes/profile/Profile.js +++ b/frontend/src/routes/profile/Profile.js @@ -20,6 +20,14 @@ export async function fetchProfile() { }); if (!response_user.ok) { const errorData = await response_user.json(); + if (response_user.status === 401) { + if (errorData.error === 'Token has expired') { + await RefreshToken(); + return fetchProfile(); // Retry fetching user details after token refresh + } + document.getElementById("logout-button").click(); + return; + } throw new Error(errorData.error); } @@ -45,12 +53,15 @@ export async function fetchProfile() { if (!matchResponse.ok) { const errorData = await matchResponse.json(); - if (errorData.error === 'Token has expired') { - await RefreshToken(); - return fetchMatches(); // Retry fetching matches after token refresh - } else { - throw new Error(errorData.error); + if (matchResponse.status === 401) { + if (errorData.error === 'Token has expired') { + await RefreshToken(); + return fetchMatches(); // Retry fetching matches after token refresh + } + document.getElementById("logout-button").click(); + return; } + throw new Error(errorData.error); } const matchData = await matchResponse.json(); diff --git a/frontend/src/routes/quickplay/Quickplay.js b/frontend/src/routes/quickplay/Quickplay.js index 82e4e64..8769822 100644 --- a/frontend/src/routes/quickplay/Quickplay.js +++ b/frontend/src/routes/quickplay/Quickplay.js @@ -45,9 +45,11 @@ export async function fetchQuickplay() { return RefreshToken().then(() => { return postGameCreate().then(handleResponse); }); - } else { - throw errorData; + } else if (response.status === 401 && errorData.error) { + document.getElementById("logout-button").click(); + return; } + throw errorData; }); } return response.json(); @@ -104,9 +106,11 @@ export async function fetchQuickplay() { return RefreshToken().then(() => { return postGameCreate().then(handleResponse); }); - } else { - throw errorData; + } else if (response.status === 401 && errorData.error) { + document.getElementById("logout-button").click(); + return; } + throw errorData; }); } return response.json(); diff --git a/frontend/src/routes/twofa/TwoFA.js b/frontend/src/routes/twofa/TwoFA.js index 3946a81..f382253 100644 --- a/frontend/src/routes/twofa/TwoFA.js +++ b/frontend/src/routes/twofa/TwoFA.js @@ -32,7 +32,8 @@ form.addEventListener("submit", (e) => { }) .then(res => { if (!res.ok) { - fields_warning.innerText = "invalid code"; + errorData = res.json(); + fields_warning.innerText = errorData.error; throw new Error("couldn't log in"); } document.getElementById('nav-bar').style.display = 'flex'; diff --git a/frontend/src/routes/users/Users.js b/frontend/src/routes/users/Users.js index a9c0319..dc1190a 100644 --- a/frontend/src/routes/users/Users.js +++ b/frontend/src/routes/users/Users.js @@ -35,16 +35,24 @@ export async function fetchUsers() { if (!response.ok) { const errorData = await response.json(); - if (errorData.error === 'Token has expired') { - await RefreshToken(); - return fetchUserSearch(searchValue); // Retry fetching after token refresh - } else { - throw new Error(errorData.error); + if (response.status === 401) { + if (errorData.error === 'Token has expired') { + await RefreshToken(); + return fetchUserSearch(searchValue); // Retry fetching after token refresh + } else { + document.getElementById("logout-button").click(); + return; + } } + throw new Error(errorData.error); } const data = await response.json(); const users = data.data; + if (!users) { + alert("No users found"); + return; + } let paginate_data = data.pagination; if (paginate_data) { @@ -65,7 +73,16 @@ export async function fetchUsers() { }); if (!resp.ok) { - console.log("error!"); + if (resp.status === 401) { + if (errorData.error === 'Token has expired') { + await RefreshToken(); + return fetchUserSearch(searchValue); // Retry fetching after token refresh + } else { + document.getElementById("logout-button").click(); + return; + } + } + throw new Error(errorData.error); } const userRelations = await resp.json(); @@ -168,15 +185,19 @@ export async function fetchUsers() { if (!response.ok) { const errorData = await response.json(); - if (errorData.error === 'Token has expired') { - await RefreshToken(); - return addUser(userId); // Retry adding after token refresh - } else { - throw new Error(errorData.error); + if (response.status === 401) { + if (errorData.error === 'Token has expired') { + await RefreshToken(); + return addUser(userId); // Retry adding after token refresh + } + document.getElementById("logout-button").click(); + return; } + throw new Error(errorData.error); } await response.json(); + alert("Friend request sent successfully"); navigateTo("/users"); } catch (error) { console.error(error); diff --git a/frontend/src/utils/utils.js b/frontend/src/utils/utils.js index d035c35..c2ca762 100644 --- a/frontend/src/utils/utils.js +++ b/frontend/src/utils/utils.js @@ -28,12 +28,15 @@ export const toggleHidden = (elementId) => { } + + + export let socket = null; export let userStatuses = []; let userId; export async function onlineStatus() { - if (!localStorage.getItem("access_token")) { + if (!localStorage.getItem('access_token')) { return; } try { @@ -44,28 +47,34 @@ export async function onlineStatus() { "Authorization": `Bearer ${localStorage.getItem("access_token")}`, } }); - if (!response.ok) { const errorData = await response.json(); - if (errorData.error === 'Token has expired') { - await RefreshToken(); - return onlineStatus(); // Retry after token refresh + if (response.status === 401) { + if (errorData.error === 'Token has expired') { + await RefreshToken(); + return onlineStatus(); + } + document.getElementById("logout-button").click(); + return; } else { throw new Error(errorData.error); } } - const data = await response.json(); const user = data.data[0]; userId = user.id; - // Eğer mevcut bir WebSocket bağlantısı varsa yeni bir bağlantı kurmayın + // Eğer mevcut bir WebSocket bağlantısı varsa yeni bir bağlantı kurmayın if (socket && socket.readyState === WebSocket.OPEN) { // Server'dan online_users listesini iste socket.send(JSON.stringify({ type: 'getOnlineUsers' })); return; } socket = new WebSocket(StatusServiceSocketUrl + "?user_id=" + userId); + socket.onopen = function (event) { + localStorage.setItem('status', 'Online'); + + }; socket.onmessage = function (event) { const data = JSON.parse(event.data); userStatuses = data.online_users; @@ -74,6 +83,7 @@ export async function onlineStatus() { console.error('WebSocket error: ', error); }; window.addEventListener('beforeunload', function () { + localStorage.setItem('status', 'Offline'); socket.close(); }); window.addEventListener('online', function () { @@ -82,17 +92,14 @@ export async function onlineStatus() { } }); window.addEventListener('offline', function () { + localStorage.setItem('status', 'Offline'); socket.close(); }); } catch (error) { console.error('Error: ', error); if (error.message === 'Token has expired') { - await RefreshToken().then((is_valid) => { - if (!is_valid) { - navigateTo("/login"); - } - }); + await RefreshToken(); return onlineStatus(); // Retry after token refresh } }