diff --git a/client/src/App.tsx b/client/src/App.tsx
index e5f3b04..f834bf4 100644
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -3,7 +3,7 @@ import {
createBrowserRouter,
Navigate,
} from 'react-router-dom';
-import { useState } from 'react';
+import { useEffect, useState } from 'react';
import Chat from './pages/Chat.tsx';
import Login from './pages/Login.tsx';
import Signup from './pages/Signup.tsx';
@@ -11,7 +11,9 @@ import Settings from './pages/Settings.tsx';
import Lost from './pages/404.tsx';
import { AuthContext } from './utils/AuthProvider.tsx';
import ProtectedRoutes from './utils/ProtectedRoutes.tsx';
+import PublicRoute from '@/utils/PublicRoute.tsx';
import axios from 'axios';
+import Cookies from 'js-cookie';
export const axiosClient = axios.create({
baseURL: import.meta.env.VITE_BASE_URL,
});
@@ -34,12 +36,17 @@ const router = createBrowserRouter([
],
},
{
- path: '/login',
- element: ,
- },
- {
- path: '/signup',
- element: ,
+ element: ,
+ children: [
+ {
+ path: '/login',
+ element: ,
+ },
+ {
+ path: '/signup',
+ element: ,
+ },
+ ],
},
{
path: '*',
@@ -48,12 +55,38 @@ const router = createBrowserRouter([
]);
function App() {
- const [authorized, setAuthorized] = useState(null);
+ const [authorized, setAuthorized] = useState(false);
+ const [isLoading, setIsLoading] = useState(true);
+
+ useEffect(() => {
+ async function validateToken() {
+ const token = Cookies.get('token');
+ if (!token) {
+ setAuthorized(false);
+ setIsLoading(false);
+ return;
+ }
+
+ try {
+ await axiosClient.get('/api/auth/validate', {
+ withCredentials: true,
+ });
+ setAuthorized(true);
+ } catch (e) {
+ setAuthorized(false);
+ console.log('Failed to validate token: ', e);
+ } finally {
+ setIsLoading(false);
+ }
+ }
+
+ validateToken();
+ }, []);
+
return (
-
+
);
}
-
export default App;
diff --git a/client/src/utils/AuthProvider.tsx b/client/src/utils/AuthProvider.tsx
index b86dba3..991d944 100644
--- a/client/src/utils/AuthProvider.tsx
+++ b/client/src/utils/AuthProvider.tsx
@@ -1,10 +1,13 @@
import { createContext } from 'react';
type AuthContextType = {
- authorized: boolean | null;
+ authorized: boolean;
+ isLoading: boolean;
setAuthorized: (value: boolean) => void;
};
+
export const AuthContext = createContext({
- authorized: null,
+ authorized: false,
+ isLoading: true,
setAuthorized: () => {},
});
diff --git a/client/src/utils/ProtectedRoutes.tsx b/client/src/utils/ProtectedRoutes.tsx
index d33892c..f289cd4 100644
--- a/client/src/utils/ProtectedRoutes.tsx
+++ b/client/src/utils/ProtectedRoutes.tsx
@@ -1,6 +1,5 @@
import { Navigate, Outlet } from 'react-router-dom';
import { useState, useEffect, useContext } from 'react';
-import Cookie from 'js-cookie';
import { AuthContext } from './AuthProvider.tsx';
import LoadingScreen from '../components/LoadingScreen.tsx';
import { axiosClient } from '../App.tsx';
@@ -11,37 +10,24 @@ export type UsernameType = {
};
function ProtectedRoutes() {
- const { authorized, setAuthorized } = useContext(AuthContext);
+ const { authorized, isLoading } = useContext(AuthContext);
const [user, setUser] = useState({
username: null,
user_id: null,
});
useEffect(() => {
- function validateToken() {
- const token = Cookie.get('token');
- if (!token) {
- setAuthorized(false);
- return;
- }
-
+ if (authorized) {
axiosClient
.get('/api/auth/validate', { withCredentials: true })
- .then(async (res) => {
+ .then((res) => {
setUser(res.data);
- console.log('User: ', res.data);
- setAuthorized(true);
})
- .catch((err) => {
- setAuthorized(false);
- console.log(err);
- console.log('Unauthorized');
- });
+ .catch(console.error);
}
- validateToken();
- }, [setAuthorized]);
+ }, [authorized]);
- if (authorized === null) {
+ if (isLoading) {
return ;
}
diff --git a/client/src/utils/PublicRoute.tsx b/client/src/utils/PublicRoute.tsx
new file mode 100644
index 0000000..d784e91
--- /dev/null
+++ b/client/src/utils/PublicRoute.tsx
@@ -0,0 +1,16 @@
+import { Navigate, Outlet } from 'react-router-dom';
+import { useContext } from 'react';
+import { AuthContext } from './AuthProvider';
+import LoadingScreen from '../components/LoadingScreen';
+
+function PublicRoute() {
+ const { authorized, isLoading } = useContext(AuthContext);
+
+ if (isLoading) {
+ return ;
+ }
+
+ return authorized ? : ;
+}
+
+export default PublicRoute;