From fd6c6d0799ccbf15683bf8df31479ca755b6fed0 Mon Sep 17 00:00:00 2001 From: Jason Date: Sun, 2 Jun 2024 00:08:31 -0700 Subject: [PATCH] feat: enforces frontend route projection --- frontend/lib/deletes.tsx | 25 ++++++++++++++-- frontend/lib/edits.tsx | 11 +++++++ frontend/lib/fetches.tsx | 14 +++++++-- frontend/src/App.tsx | 30 ++++++++----------- .../src/components/Friends_List_Component.tsx | 17 ++++------- frontend/src/pages/IndividualGroupPage.tsx | 3 ++ frontend/src/pages/ItemsPage.tsx | 2 ++ frontend/src/pages/MyGroupsPage.tsx | 6 ++-- frontend/src/pages/ProfilePage.tsx | 11 ++++++- 9 files changed, 81 insertions(+), 38 deletions(-) diff --git a/frontend/lib/deletes.tsx b/frontend/lib/deletes.tsx index 2a2d2ba..9672d5f 100644 --- a/frontend/lib/deletes.tsx +++ b/frontend/lib/deletes.tsx @@ -49,6 +49,9 @@ export const handleDeleteItem = async (itemId: string) => { try { const response = await fetch(`${vite_backend_url}/items/${itemId}`, { method: "DELETE", + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, }); if (!response.ok) { throw new Error(`Error: ${response.statusText}`); @@ -82,7 +85,12 @@ export const handleDeleteGroupFromUsers = async ( try { // Iterate over each userId for (const userId of userIds) { - const response = await fetch(`${vite_backend_url}/users/${userId}`); + const response = await fetch(`${vite_backend_url}/users/${userId}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); if (response.ok) { const user = await response.json(); const userGroups = user.groups; @@ -100,6 +108,7 @@ export const handleDeleteGroupFromUsers = async ( method: "PATCH", headers: { "Content-Type": "application/json", + Authorization: `Bearer ${localStorage.getItem("token")}`, }, body: JSON.stringify({ groups: updatedGroups }), }, @@ -124,7 +133,12 @@ export const handleDeleteBasketFromGroup = async ( basketId: string, ) => { try { - const response = await fetch(`${vite_backend_url}/groups/${groupId}`); + const response = await fetch(`${vite_backend_url}/groups/${groupId}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); if (response.ok) { const group = await response.json(); const groupBaskets = group.baskets; @@ -144,6 +158,7 @@ export const handleDeleteBasketFromGroup = async ( method: "PATCH", headers: { "Content-Type": "application/json", + Authorization: `Bearer ${localStorage.getItem("token")}`, }, body: JSON.stringify({ baskets: updatedBaskets }), }, @@ -165,7 +180,11 @@ export const handleDeleteBasketFromGroup = async ( export const handleDeleteAllItemsInBasket = async (basketId: string) => { try { // Fetch all items in the basket - const response = await fetch(`${vite_backend_url}/baskets/${basketId}`); + const response = await fetch(`${vite_backend_url}/baskets/${basketId}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + }); if (!response.ok) { throw new Error(`Error fetching items: ${response.statusText}`); } diff --git a/frontend/lib/edits.tsx b/frontend/lib/edits.tsx index 41c21a4..4bb789d 100644 --- a/frontend/lib/edits.tsx +++ b/frontend/lib/edits.tsx @@ -186,3 +186,14 @@ export const addUserToGroup = async (group: IGroup, users: ObjectId[]) => { body: JSON.stringify({ members: users }), }); }; + +export const addFriendToUser = async (user: IUser, updatedFriends: ObjectId[]) => { + return fetch(`${vite_backend_url}/users/${user._id}`, { + method: "PATCH", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + body: JSON.stringify({ friends: updatedFriends }), + }); +} diff --git a/frontend/lib/fetches.tsx b/frontend/lib/fetches.tsx index 4d7fb0c..7b244eb 100644 --- a/frontend/lib/fetches.tsx +++ b/frontend/lib/fetches.tsx @@ -43,11 +43,21 @@ export const fetchGroupById = async (groupId: string) => { }; export const fetchGroup = async (groupId: string) => { - return fetch(`${vite_backend_url}/groups/${groupId}`); + return fetch(`${vite_backend_url}/groups/${groupId}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); }; export const fetchUser = async (userId: ObjectId) => { - return fetch(`${vite_backend_url}/users/${userId}`); + return fetch(`${vite_backend_url}/users/${userId}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); }; export const fetchUserWithString = async (userId: string) => { diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 303af77..279c948 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -6,7 +6,6 @@ import SignupPage from "./pages/SignupPage"; import ItemsPage from "./pages/ItemsPage"; import NavbarSignedOut from "./components/NavbarSignedOut"; import NavbarSignedIn from "./components/NavbarSignedIn"; -import Friends_List from "./components/Friends_List_Component"; import ProfilePage from "./pages/ProfilePage"; import GroupPage from "./pages/MyGroupsPage"; import IndividualGroupPage from "./pages/IndividualGroupPage"; @@ -84,7 +83,7 @@ function App() { updateState={{ setUser, setToken }} /> ) : ( - + )} } /> @@ -92,19 +91,6 @@ function App() { path="/login" element={} /> - } - /> - - } - /> + } /> - {/* added route for individual group page */} } @@ -134,6 +122,12 @@ function App() { /> } /> + + } + /> diff --git a/frontend/src/components/Friends_List_Component.tsx b/frontend/src/components/Friends_List_Component.tsx index 51cc0f2..cc143fe 100644 --- a/frontend/src/components/Friends_List_Component.tsx +++ b/frontend/src/components/Friends_List_Component.tsx @@ -25,10 +25,12 @@ import { fetchUser, fetchUserGroupsByUser, fetchUserFriendsByUser, + fetchUserWithString, } from "../../lib/fetches"; import { removeFriendFromUserByFriendId } from "../../lib/deletes"; import { addFriendToGroup } from "../../lib/fetches"; import { ObjectId } from "mongoose"; +import { addFriendToUser } from "../../lib/edits"; type Props = { initialUserId?: string; @@ -89,8 +91,8 @@ const Friends_List: React.FC = ({ if (userId == LoggedInUser) { console.log("Cannot add yourself as friend"); } else { - const res = await fetch(`http://localhost:3001/users/${userId}`); - const res2 = await fetch(`http://localhost:3001/users/${LoggedInUser}`); + const res = await fetchUserWithString(userId); + const res2 = await fetchUser(LoggedInUser); let user; let friend; if (res.ok && res2.ok) { @@ -101,16 +103,7 @@ const Friends_List: React.FC = ({ user.friends.push(friend._id); console.log("Pushed to list"); - const updatedRes = await fetch( - `http://localhost:3001/users/${LoggedInUser}`, - { - method: "PATCH", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify({ friends: user.friends }), - }, - ); + const updatedRes = await addFriendToUser(user, user.friends); console.log("Past Patch"); if (updatedRes.ok) { setFriends([...friends, friend]); diff --git a/frontend/src/pages/IndividualGroupPage.tsx b/frontend/src/pages/IndividualGroupPage.tsx index 923ce8f..c96db9b 100644 --- a/frontend/src/pages/IndividualGroupPage.tsx +++ b/frontend/src/pages/IndividualGroupPage.tsx @@ -111,6 +111,9 @@ const IndividualGroupPage: React.FC = ({ useEffect(() => { console.log(`Loading: ${loading}`); + if (!LoggedInUser) { + navigate("/login"); + } if (groupId) { fetchGroup(String(groupId)) .then((group) => { diff --git a/frontend/src/pages/ItemsPage.tsx b/frontend/src/pages/ItemsPage.tsx index 32d7235..eacb22d 100644 --- a/frontend/src/pages/ItemsPage.tsx +++ b/frontend/src/pages/ItemsPage.tsx @@ -50,6 +50,8 @@ const ItemsPage: React.FC = ({ .catch((err) => { console.log(`Terrible error occurred! ${err}`); }); + } else { + navigate("/login"); } }, [stateVariable.user]); diff --git a/frontend/src/pages/MyGroupsPage.tsx b/frontend/src/pages/MyGroupsPage.tsx index 1b195f1..cfdbdf9 100644 --- a/frontend/src/pages/MyGroupsPage.tsx +++ b/frontend/src/pages/MyGroupsPage.tsx @@ -13,10 +13,9 @@ import SkeletonGroup from "../components/SkeletonGroup"; import { IoIosSwap } from "react-icons/io"; import SearchBar from "../components/SearchBar"; import PageSelector from "../components/PageSelector"; -import { Link } from "react-router-dom"; +import { Link, useNavigate } from "react-router-dom"; import "../styles/MyGroups.css"; import NewGroupOptions from "../components/NewGroupOptions"; - import { IGroup } from "../../../backend/models/groupSchema"; import { IUser } from "../../../backend/models/userSchema"; import { fetchGroups } from "../../lib/fetches"; @@ -42,6 +41,7 @@ const GroupPage: React.FC = ({ const [loading, setLoading] = useState(true); const gridDims = [2, 4]; const skelIds: number[] = []; + const navigate = useNavigate(); for (let i = 0; i < gridDims[0] * gridDims[1]; i++) { skelIds.push(i); } @@ -71,6 +71,8 @@ const GroupPage: React.FC = ({ .catch((err) => { console.log(`Terrible error occurred! ${err}`); }); + } else { + navigate("/login"); } }, [stateVariable.user]); diff --git a/frontend/src/pages/ProfilePage.tsx b/frontend/src/pages/ProfilePage.tsx index 4b8b88b..6b9a8c7 100644 --- a/frontend/src/pages/ProfilePage.tsx +++ b/frontend/src/pages/ProfilePage.tsx @@ -1,7 +1,8 @@ -import React from "react"; +import React, { useEffect } from "react"; import { Box, Grid, GridItem, Heading } from "@chakra-ui/react"; import UserProfile from "../components/UserProfile"; import Friends_List from "../components/Friends_List_Component"; +import { useNavigate } from "react-router-dom"; interface ProfilePageProps { LoggedInUser: string; @@ -12,6 +13,14 @@ const ProfilePage: React.FC = ({ LoggedInUser, avatarColor, }) => { + const navigate = useNavigate(); + useEffect(() => { + if (!LoggedInUser) { + navigate("/login"); + } + } + ); + return (