From 470482bc93552907e77bb2f3fb89bf90affa19a0 Mon Sep 17 00:00:00 2001 From: Rafael Cenzano <32753063+RafaelCenzano@users.noreply.github.com> Date: Sat, 22 Feb 2025 00:54:27 -0500 Subject: [PATCH 01/10] Remove uneeded page --- src/shared/pages/LoginRedirect.tsx | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 src/shared/pages/LoginRedirect.tsx diff --git a/src/shared/pages/LoginRedirect.tsx b/src/shared/pages/LoginRedirect.tsx deleted file mode 100644 index 29e33a83..00000000 --- a/src/shared/pages/LoginRedirect.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from "react"; -import SEO from "../components/SEO.tsx"; -import { Link } from "react-router-dom"; -const LoginRedirect = () => { - return ( - <> -

Whoops!

-

It looks like you're not logged in. Click the button below and log in to see this page

-
- Log In -
- - ); -}; -export default LoginRedirect; \ No newline at end of file From d00db21ca8e6abd6cf6b09f500f1551476e28652 Mon Sep 17 00:00:00 2001 From: Rafael Cenzano <32753063+RafaelCenzano@users.noreply.github.com> Date: Sat, 22 Feb 2025 00:54:34 -0500 Subject: [PATCH 02/10] Fix function properties --- src/staff/components/DepartmentHeading.tsx | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/staff/components/DepartmentHeading.tsx b/src/staff/components/DepartmentHeading.tsx index 47b17969..993fd14b 100644 --- a/src/staff/components/DepartmentHeading.tsx +++ b/src/staff/components/DepartmentHeading.tsx @@ -1,8 +1,14 @@ import React from "react"; -import PropTypes from "prop-types"; import { Link } from "react-router-dom"; -const DepartmentHeading = ({ name, description, image, website }) => { +interface DepartmentHeadingProps { + name: string; + description: string; + image: string; + website?: string; +} + +export default function DepartmentHeading({ name, description, image, website }: DepartmentHeadingProps) { return (
@@ -11,18 +17,10 @@ const DepartmentHeading = ({ name, description, image, website }) => {

{name}

{description}

- + {website && {website} - + }
); }; - -DepartmentHeading.propTypes = { - name: PropTypes.string.isRequired, - description: PropTypes.string.isRequired, - image: PropTypes.string.isRequired, - website: PropTypes.string, -}; -export default DepartmentHeading; From 53ae19eac9de727247145efad06f982caa0b39cb Mon Sep 17 00:00:00 2001 From: Rafael Cenzano <32753063+RafaelCenzano@users.noreply.github.com> Date: Sat, 22 Feb 2025 00:55:20 -0500 Subject: [PATCH 03/10] Update to cookie auth system instead of local storage --- src/auth/Logout.tsx | 8 +-- src/auth/Token.tsx | 20 ++++--- src/context/AuthContext.tsx | 56 +++++++++--------- .../Profile/ProfileOpportunities.tsx | 8 +-- src/shared/pages/Profile.tsx | 6 +- src/staff/components/CreationForms.tsx | 58 ++++++++----------- src/staff/pages/Department.tsx | 11 ++-- src/staff/pages/Departments.tsx | 7 +-- src/staff/pages/Staff.tsx | 14 ++--- 9 files changed, 87 insertions(+), 101 deletions(-) diff --git a/src/auth/Logout.tsx b/src/auth/Logout.tsx index 08b71716..62e5440f 100644 --- a/src/auth/Logout.tsx +++ b/src/auth/Logout.tsx @@ -14,11 +14,7 @@ export default function LogoutRedirection() { const response = await fetch( `${process.env.REACT_APP_BACKEND_SERVER}/logout`, { - method: "GET", - credentials: "include", // to send cookies or session data - headers: { - Authorization: `Bearer ${auth.token}`, - }, + credentials: "include", } ); if (response.ok) { @@ -32,7 +28,7 @@ export default function LogoutRedirection() { } } logoutUser(); - }, [logout, auth.token]); + }, [logout]); return null; // Since this component doesn't need to render anything }; \ No newline at end of file diff --git a/src/auth/Token.tsx b/src/auth/Token.tsx index 411cf617..90f19f77 100644 --- a/src/auth/Token.tsx +++ b/src/auth/Token.tsx @@ -3,7 +3,11 @@ import { useEffect } from "react"; export default function Token() { - const { login } = useAuth(); + const { auth, login } = useAuth(); + + if (auth.isAuthenticated) { + window.location.href = "/"; + } const urlParams = new URLSearchParams(window.location.search); const code = urlParams.get("code"); @@ -19,12 +23,14 @@ export default function Token() { }) .then((response) => response.json()) .then((data) => { - const token = data.token; - if (token) { - login(token); - window.location.href = "/"; - return null; - } + const registered = data.registered; + login(); + console.log("Registered:", registered); + // if (registered) { + window.location.href = "/"; + return null; + // } + // TODO: Redirect to registration page }) .catch((error) => console.error("Error fetching token:", error)); } diff --git a/src/context/AuthContext.tsx b/src/context/AuthContext.tsx index 83c6660a..f6efd3d5 100644 --- a/src/context/AuthContext.tsx +++ b/src/context/AuthContext.tsx @@ -1,53 +1,55 @@ -import React, { createContext, useState, useContext, useEffect } from 'react'; -import { ReactNode } from 'react'; +import React, { createContext, useState, useContext } from 'react'; +import { ReactNode, useEffect } from 'react'; const AuthContext = createContext<{ - auth: { isAuthenticated: boolean; token: string | null }; - login: (token: string) => void; + auth: { isAuthenticated: boolean }; + login: () => void; logout: () => void; - loadToken: () => void; }>({ - auth: { isAuthenticated: false, token: null }, + auth: { isAuthenticated: false }, login: () => { }, logout: () => { }, - loadToken: () => { } }); interface AuthProviderProps { children: ReactNode; } export const AuthProvider = ({ children }: AuthProviderProps) => { - const [auth, setAuth] = useState<{ isAuthenticated: boolean; token: string | null }>({ + const [auth, setAuth] = useState<{ isAuthenticated: boolean }>({ isAuthenticated: false, - token: null, }); - const login = (token: string) => { - setAuth({ isAuthenticated: true, token }); - // Save token to localStorage for persistence - localStorage.setItem('jwt', token); - }; - - const logout = () => { - setAuth({ isAuthenticated: false, token: null }); - // Clear token from localStorage - localStorage.removeItem('jwt'); - }; - - const loadToken = () => { - const savedToken = localStorage.getItem('jwt'); - if (savedToken) { - setAuth({ isAuthenticated: true, token: savedToken }); + const checkAuth = async () => { + try { + const response = await fetch(`${process.env.REACT_APP_BACKEND_SERVER}/authcheck`, { + credentials: "include", + }); + if (response.ok) { + setAuth({ isAuthenticated: true }); + } else { + setAuth({ isAuthenticated: false }); + } + } catch (error) { + console.error("Auth check failed:", error); + setAuth({ isAuthenticated: false }); } }; useEffect(() => { - loadToken(); + checkAuth(); // Run this on mount to persist session state }, []); + const login = () => { + setAuth({ isAuthenticated: true }); + }; + + const logout = () => { + setAuth({ isAuthenticated: false }); + }; + return ( - + {children} ); diff --git a/src/shared/components/Profile/ProfileOpportunities.tsx b/src/shared/components/Profile/ProfileOpportunities.tsx index cc659444..881bca2b 100644 --- a/src/shared/components/Profile/ProfileOpportunities.tsx +++ b/src/shared/components/Profile/ProfileOpportunities.tsx @@ -1,19 +1,15 @@ import React from "react"; import LargeTextCard from "../UIElements/LargeTextCard.tsx"; import { useState, useEffect } from "react"; -import { useAuth } from "../../../context/AuthContext.tsx"; export default function ProfileOpportunities({ id, staff }: { id: string, staff: boolean }) { - const { auth } = useAuth(); const [opportunities, setOpportunities] = useState | null | "no response">(null); useEffect(() => { async function setData() { const response = await fetch( `${process.env.REACT_APP_BACKEND_SERVER}/${staff ? "staff" : "profile"}/opportunities/${id}`, { - headers: { - Authorization: `Bearer ${auth.token}`, - }, + credentials: "include", } ); @@ -26,7 +22,7 @@ export default function ProfileOpportunities({ id, staff }: { id: string, staff: } setData(); - }, [auth.token, id, staff]); + }, [id, staff]); const opportunityList = (
diff --git a/src/shared/pages/Profile.tsx b/src/shared/pages/Profile.tsx index 5859efaf..9135224b 100644 --- a/src/shared/pages/Profile.tsx +++ b/src/shared/pages/Profile.tsx @@ -31,9 +31,7 @@ export default function ProfilePage() { const fetchProfile = async () => { const response = await fetch( `${process.env.REACT_APP_BACKEND_SERVER}/profile`, { - headers: { - Authorization: `Bearer ${auth.token}`, - }, + credentials: "include", } ); @@ -48,7 +46,7 @@ export default function ProfilePage() { } }; fetchProfile(); - }, [auth.token]); + }, []); // const editButton = ( //