diff --git a/backend/routes/user.js b/backend/routes/user.js
index 5a109d9..38a55dc 100644
--- a/backend/routes/user.js
+++ b/backend/routes/user.js
@@ -10,12 +10,18 @@ const { catchAsync } = require("../util/errors");
router.use(
catchAsync(async (req, res, next) => {
let userID = req.url.split("/")[1];
+ if (userID?.length !== 24)
+ return res.status(404).json({ userMessage: "User not found", devMessage: "Invalid user ID" });
let userData = await User.findById(userID);
if (userData) {
req.userData = userData;
next();
} else {
- res.status(404).json({ success: false, error: { message: "User not found" } });
+ res.status(404).json({
+ success: false,
+ userMessage: "User not found",
+ devMessage: "User ID does not exists",
+ });
}
})
);
@@ -24,23 +30,12 @@ router.use(
// get user details
router.get(
"/:userid",
- checkAuth,
catchAsync(async (req, res, next) => {
let userData = req.userData;
- let {
- id,
- username,
- email,
- fname,
- lname,
- country,
- location,
- } = userData;
+ let { id, username, email, fname, lname, country, location } = userData;
let friends = await userData.getFriends();
let games = await userData.getGames();
- let resData = { id, username, email, friends, fname, lname, country, location, games };
- console.log(resData)
- return res.json({ success: true, data: resData });
+ return res.status(200).json({ id, username, email, friends, fname, lname, country, location, games });
})
);
@@ -52,7 +47,7 @@ router.patch(
catchAsync(async (req, res, next) => {
let { userid } = req.params;
let updatedData = req.body;
- console.log('Updated data: ',updatedData)
+ console.log("Updated data: ", updatedData);
// console.log(updatedData)
await User.findByIdAndUpdate(userid, { ...updatedData });
let { id, username, email, fname, lname, location, country, fullName } = await User.findById(userid);
diff --git a/frontend/index.html b/frontend/index.html
index 4b98589..28b631b 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -1,20 +1,23 @@
-
-
-
-
- Chess
-
-
-
-
-
-
+
+
+
+
+ Chess
+
+
+
+
+
+
+
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index c0a59ee..3a71efb 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -16,6 +16,7 @@
"@radix-ui/react-icons": "^1.3.0",
"@tabler/icons-react": "^2.23.0",
"chess.js": "^1.0.0-beta.6",
+ "js-cookie": "^3.0.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.45.2",
@@ -2953,6 +2954,14 @@
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true
},
+ "node_modules/js-cookie": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
+ "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
+ "engines": {
+ "node": ">=14"
+ }
+ },
"node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 1c30563..e126d72 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -18,6 +18,7 @@
"@radix-ui/react-icons": "^1.3.0",
"@tabler/icons-react": "^2.23.0",
"chess.js": "^1.0.0-beta.6",
+ "js-cookie": "^3.0.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.45.2",
diff --git a/frontend/src/components/Logout.jsx b/frontend/src/components/Logout.jsx
index d2a16f4..65374be 100644
--- a/frontend/src/components/Logout.jsx
+++ b/frontend/src/components/Logout.jsx
@@ -24,6 +24,7 @@ const Logout = () => {
console.log('Logged out')
localStorage.removeItem('user');
close();
+ localStorage.removeItem('loggedIn');
return navigate('/login');
} else {
return setErrorMsg(resData.userMessage || "Something went wrong")
diff --git a/frontend/src/components/MainLoader.jsx b/frontend/src/components/MainLoader.jsx
index 4a5551b..72c16ee 100644
--- a/frontend/src/components/MainLoader.jsx
+++ b/frontend/src/components/MainLoader.jsx
@@ -1,13 +1,31 @@
import React from 'react'
+import { createPortal } from 'react-dom'
import loaderImage from '../assets/images/chess_board_loader.png'
-import { Loader } from '@mantine/core'
+import { Loader, Title } from '@mantine/core'
-const MainLoader = () => {
+const MainLoader = ({ errorMessage }) => {
return (
-
-

-
-
+ <>
+ {
+ createPortal(
+

+ {
+ errorMessage
+ ?
+
+ {errorMessage}
+
+ :
+
+ }
+
, document.querySelector('#main-loader'))
+
+ }
+ >
+ //
+ //

+ //
+ //
)
}
diff --git a/frontend/src/context/user-data-context.jsx b/frontend/src/context/user-data-context.jsx
index f7dda22..7358627 100644
--- a/frontend/src/context/user-data-context.jsx
+++ b/frontend/src/context/user-data-context.jsx
@@ -1,32 +1,32 @@
import React, { createContext, useEffect, useState } from 'react'
-import { getAuthToken, getUserData } from '../../utils/auth';
+import Cookie from 'js-cookie'
export const UserDataContext = createContext();
const UserDataContextProvider = ({ children }) => {
- let { id: userid } = getUserData();
+ // TODO: use more secure mechanism insted of localstorage
+ const [isLoggedIn, setIsLoggedIn] = useState(JSON.parse(localStorage.getItem('loggedIn')));
const [user, setUser] = useState(null);
- const [friends, setFriends] = useState(null)
- const [games, setGames] = useState(null);
+ const [errorMessage, setErrorMessage] = useState("");
async function fetchUserDetails() {
- let url = `${import.meta.env.VITE_BACKEND_HOST}/api/user/${userid}`;
- let response = await fetch(url, {
- headers: {
- Authorization: `Bearer ${getAuthToken()}`
+ try {
+ if (isLoggedIn) {
+ let { id: userid } = JSON.parse(localStorage.getItem('user'));
+ let userDetailsUrl = `${import.meta.env.VITE_BACKEND_HOST}/api/user/${userid}`
+ const response = await fetch(userDetailsUrl, {
+ credentials: 'include'
+ });
+ const resData = await response.json();
+ if (response.ok) {
+ setUser(resData);
+ } else {
+ console.log(resData.devMessage);
+ setErrorMessage(resData.userMessage);
+ }
}
- });
- let resData = await response.json();
- if (resData.success) {
- let { id, username, email, friends: _friends_, fname, lname, fullName, country, location, games: _games_ } = resData.data;
- setUser({ id, username, email, fname, lname, fullName, country, location })
- setFriends(_friends_)
- setGames(_games_)
- localStorage.setItem('user', JSON.stringify({ id, username, email, fname, lname, fullName, country, location }));
- localStorage.setItem('friends', JSON.stringify(_friends_));
- localStorage.setItem('games', JSON.stringify(_games_));
- } else {
- throw resData.error
+ } catch (err) {
+ setErrorMessage("Something went wrong");
}
}
@@ -35,7 +35,7 @@ const UserDataContextProvider = ({ children }) => {
}, []);
return (
-
+
{children}
)
diff --git a/frontend/src/layout/MainLayout.jsx b/frontend/src/layout/MainLayout.jsx
index 9e42dc7..0604802 100644
--- a/frontend/src/layout/MainLayout.jsx
+++ b/frontend/src/layout/MainLayout.jsx
@@ -1,9 +1,10 @@
import { AppShell, Burger, Container, Header, MediaQuery, Navbar, Paper, Text, createStyles, useMantineTheme } from '@mantine/core'
-import React, { useState } from 'react'
+import React, { useContext, useState } from 'react'
import NavbarLinks from '../components/NavbarLinks';
import { Outlet } from 'react-router-dom'
import Logout from '../components/Logout';
-import UserDataContextProvider from '../context/user-data-context';
+import UserDataContextProvider, { UserDataContext } from '../context/user-data-context';
+import MainLoader from '../components/MainLoader';
const useStyles = createStyles((theme) => ({
body: {
@@ -26,6 +27,12 @@ const MainLayout = () => {
const { classes } = useStyles();
const theme = useMantineTheme();
const [opened, setOpened] = useState(false);
+ const { isLoggedIn,errorMessage } = useContext(UserDataContext);
+
+ if (!isLoggedIn) {
+ return
+ }
+
return (
diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx
index 776e19d..fff52ec 100644
--- a/frontend/src/main.jsx
+++ b/frontend/src/main.jsx
@@ -3,9 +3,12 @@ import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './index.css'
import { MantineProvider } from '@mantine/styles'
+import UserDataContextProvider from './context/user-data-context.jsx'
ReactDOM.createRoot(document.getElementById('root')).render(
-
-
-
+
+
+
+
+
)
\ No newline at end of file
diff --git a/frontend/src/pages/Authentication/Authentication.jsx b/frontend/src/pages/Authentication/Authentication.jsx
index f826602..f2669c5 100644
--- a/frontend/src/pages/Authentication/Authentication.jsx
+++ b/frontend/src/pages/Authentication/Authentication.jsx
@@ -1,8 +1,9 @@
-import React, { useState } from 'react';
+import React, { useContext, useState } from 'react';
import { Button, Card, Container, Text, TextInput, Title } from '@mantine/core';
import { Form, redirect, useNavigate } from 'react-router-dom';
import { ZodError, z } from 'zod';
import { useForm } from 'react-hook-form'
+import { UserDataContext } from '../../context/user-data-context';
let host = import.meta.env.VITE_BACKEND_HOST;
@@ -52,6 +53,7 @@ const AuthenticationPage = (props) => {
};
const LoginForm = () => {
+ const { setIsLoggedIn } = useContext(UserDataContext)
const { register, handleSubmit, setError, formState: { errors } } = useForm();
const [errorMsg, setErrorMsg] = useState("")
const [isLoading, setIsLoading] = useState(false);
@@ -67,9 +69,11 @@ const LoginForm = () => {
setIsLoading(false);
if (response.ok) {
localStorage.setItem('user', JSON.stringify(resData.user))
+ localStorage.setItem('loggedIn', true);
+ setIsLoggedIn(true);
return navigate('/');
} else {
- setErrorMsg(resData.userMessage || "Something went wrong")
+ setErrorMsg(resData.userMessage || "Something went wrong");
}
} catch (err) {
setIsLoading(false);
@@ -99,6 +103,7 @@ const LoginForm = () => {
const SignupForm = () => {
const navigate = useNavigate();
+ const { setIsLoggedIn } = useContext(UserDataContext)
const { register, handleSubmit, setError, formState: { errors } } = useForm();
const [errorMsg, setErrorMsg] = useState("")
const [isLoading, setIsLoading] = useState(false);
@@ -112,6 +117,8 @@ const SignupForm = () => {
const resData = await response.json();
if (response.ok) {
localStorage.setItem('user', JSON.stringify(resData.user))
+ localStorage.setItem('loggedIn', true);
+ setIsLoggedIn(true);
return navigate('/');
} else {
setIsLoading(false);
diff --git a/frontend/src/pages/Settings/Profile.jsx b/frontend/src/pages/Settings/Profile.jsx
index 9cd54a4..c270f45 100644
--- a/frontend/src/pages/Settings/Profile.jsx
+++ b/frontend/src/pages/Settings/Profile.jsx
@@ -4,12 +4,13 @@ import { getAuthToken, getUserData } from '../../../utils/auth'
import { UserDataContext } from '../../context/user-data-context'
import { useForm } from '@mantine/form'
import { Form } from 'react-router-dom'
+import MainLoader from '../../components/MainLoader'
const Profile = () => {
let { user } = useContext(UserDataContext);
- if(!user) {
- return
+ if (!user) {
+ return
}
let { username, email, fname, lname, country, location } = user;
@@ -83,7 +84,7 @@ export const action = async ({ request }) => {
method: 'PATCH',
headers: {
Authorization: `Bearer ${getAuthToken()}`,
- 'Content-Type':'application/json'
+ 'Content-Type': 'application/json'
}
})
const resData = await response.json();