From a9a246e99e995f53a75122776393401f8a1b8fff Mon Sep 17 00:00:00 2001 From: Jason Date: Fri, 31 May 2024 12:40:42 -0700 Subject: [PATCH 1/4] user auth --- frontend/lib/deletes.tsx | 7 +++ frontend/lib/edits.tsx | 5 ++ frontend/lib/fetches.tsx | 109 +++++++++++++++++++++++++++++++++++++-- frontend/lib/posts.tsx | 2 + 4 files changed, 118 insertions(+), 5 deletions(-) diff --git a/frontend/lib/deletes.tsx b/frontend/lib/deletes.tsx index 9d679ee..9ad888f 100644 --- a/frontend/lib/deletes.tsx +++ b/frontend/lib/deletes.tsx @@ -9,6 +9,9 @@ export const handleDeleteGroup = async (groupId: string) => { try { const response = await fetch(`${vite_backend_url}/groups/${groupId}`, { method: "DELETE", + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, }); if (!response.ok) { throw new Error(`Error: ${response.statusText}`); @@ -23,6 +26,9 @@ export const handleDeleteBasket = async (basketId: string) => { try { const response = await fetch(`${vite_backend_url}/baskets/${basketId}`, { method: "DELETE", + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, }); if (!response.ok) { throw new Error(`Error: ${response.statusText}`); @@ -44,6 +50,7 @@ export const removeFriendFromUserByFriendId = async ( method: "DELETE", headers: { "Content-Type": "application/json", + Authorization: `Bearer ${localStorage.getItem("token")}`, }, body: JSON.stringify({ friendId: friendId }), }, diff --git a/frontend/lib/edits.tsx b/frontend/lib/edits.tsx index f1bf9d7..41c21a4 100644 --- a/frontend/lib/edits.tsx +++ b/frontend/lib/edits.tsx @@ -44,6 +44,7 @@ export const editGroup = async (groupId: string, groupData: updatedGroup) => { method: "PATCH", headers: { "Content-Type": "application/json", + Authorization: `Bearer ${localStorage.getItem("token")}`, }, body: JSON.stringify(groupData), }); @@ -57,6 +58,7 @@ export const editBasket = async ( method: "PATCH", headers: { "Content-Type": "application/json", + Authorization: `Bearer ${localStorage.getItem("token")}`, }, body: JSON.stringify(basketData), }); @@ -70,6 +72,7 @@ export const addItemToBasket = async ( method: "PATCH", headers: { "Content-Type": "application/json", + Authorization: `Bearer ${localStorage.getItem("token")}`, }, body: JSON.stringify({ items: basketItems }), }); @@ -80,6 +83,7 @@ export const editItem = async (itemId: string, itemData: updatedItem) => { method: "PATCH", headers: { "Content-Type": "application/json", + Authorization: `Bearer ${localStorage.getItem("token")}`, }, body: JSON.stringify(itemData), }); @@ -155,6 +159,7 @@ export const editUser = async ( method: "PATCH", headers: { "Content-Type": "application/json", + Authorization: `Bearer ${localStorage.getItem("token")}`, }, body: JSON.stringify(userData), }); diff --git a/frontend/lib/fetches.tsx b/frontend/lib/fetches.tsx index 15f8b8a..62e0810 100644 --- a/frontend/lib/fetches.tsx +++ b/frontend/lib/fetches.tsx @@ -6,16 +6,43 @@ import { ObjectId } from "mongoose"; const vite_backend_url = import.meta.env.VITE_BACKEND_URL as string; export const fetchBasket = async (basketId: string) => { +<<<<<<< Updated upstream return fetch(`${vite_backend_url}/baskets/${basketId}`); }; export const fetchItem = async (itemId: string) => { return fetch(`${vite_backend_url}/items/${itemId}`); +======= + return fetch(`http://localhost:3001/baskets/${basketId}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); +}; + +export const fetchItem = async (itemId: string) => { + return fetch(`http://localhost:3001/items/${itemId}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); +>>>>>>> Stashed changes }; export const fetchGroupById = async (groupId: string) => { try { +<<<<<<< Updated upstream const res = await fetch(`${vite_backend_url}/groups/${groupId}`); +======= + const res = await fetch(`http://localhost:3001/groups/${groupId}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); +>>>>>>> Stashed changes if (res.ok) { return res.json(); } else { @@ -27,16 +54,43 @@ export const fetchGroupById = async (groupId: string) => { }; export const fetchUser = async (userId: ObjectId) => { +<<<<<<< Updated upstream return fetch(`${vite_backend_url}/users/${userId}`); }; export const fetchUserWithString = async (userId: string) => { return fetch(`${vite_backend_url}/users/${userId}`); +======= + return fetch(`http://localhost:3001/users/${userId}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); +}; + +export const fetchUserWithString = async (userId: string) => { + return fetch(`http://localhost:3001/users/${userId}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); +>>>>>>> Stashed changes }; export const fetchUserGroupsByUser = async (user: IUser) => { const groupPromises = user.groups.map(async (group: ObjectId) => { +<<<<<<< Updated upstream const res = await fetch(`${vite_backend_url}/groups/${group}`); +======= + const res = await fetch(`http://localhost:3001/groups/${group}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); +>>>>>>> Stashed changes if (res.status === 200) { const data = await res.json(); return data; @@ -49,7 +103,16 @@ export const fetchUserGroupsByUser = async (user: IUser) => { export const fetchUserFriendsByUser = async (user: IUser) => { const friendPromises = user.friends.map(async (friend: ObjectId) => { +<<<<<<< Updated upstream const res = await fetch(`${vite_backend_url}/users/${friend}`); +======= + const res = await fetch(`http://localhost:3001/users/${friend}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); +>>>>>>> Stashed changes if (res.status === 200) { const data = await res.json(); return data; @@ -62,7 +125,16 @@ export const fetchUserFriendsByUser = async (user: IUser) => { export const addFriendToGroup = async (friendId: string, groupId: string) => { try { +<<<<<<< Updated upstream const res = await fetch(`${vite_backend_url}/users/${friendId}`); +======= + const res = await fetch(`http://localhost:3001/users/${friendId}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); +>>>>>>> Stashed changes let friend; if (res.ok) { @@ -77,6 +149,7 @@ export const addFriendToGroup = async (friendId: string, groupId: string) => { method: "PATCH", headers: { "Content-Type": "application/json", + Authorization: `Bearer ${localStorage.getItem("token")}`, }, body: JSON.stringify({ groups: friend.groups }), }, @@ -99,7 +172,12 @@ export const addFriendToGroup = async (friendId: string, groupId: string) => { export const fetchGroupBaskets = async (group: IGroup) => { const basketPromises = group.baskets.map(async (basket) => { - const res = await fetch(`${vite_backend_url}/baskets/${basket}`); + const res = await fetch(`${vite_backend_url}/baskets/${basket}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); if (res.status === 200) { const data = await res.json(); return data; @@ -117,7 +195,12 @@ export const fetchBasketItems = async (basket: IBasket) => { return []; } const itemPromises = basket.items.map(async (item) => { - const res = await fetch(`${vite_backend_url}/items/${item}`); + const res = await fetch(`${vite_backend_url}/items/${item}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); if (res.status === 200) { const data = await res.json(); return data; @@ -129,7 +212,12 @@ export const fetchBasketItems = async (basket: IBasket) => { }; export const fetchUserBaskets = async (userId: string) => { - const res = await fetch(`${vite_backend_url}/baskets`); + const res = await fetch(`${vite_backend_url}/baskets`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); if (res.status === 200) { const allBaskets = await res.json(); const userBaskets = [] as IBasket[]; @@ -144,7 +232,12 @@ export const fetchUserBaskets = async (userId: string) => { export const fetchGroups = async (userGroups: ObjectId[]) => { const groupPromises = userGroups.map(async (group) => { - const res = await fetch(`${vite_backend_url}/groups/${group}`); + const res = await fetch(`${vite_backend_url}/groups/${group}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); if (res.status === 200) { const data = await res.json(); return data; @@ -159,7 +252,12 @@ export const fetchMembers = async (memberIds: ObjectId[]) => { try { const fetchedMembers = await Promise.all( memberIds.map(async (memberId) => { - const res = await fetch(`${vite_backend_url}/users/${memberId}`); + const res = await fetch(`${vite_backend_url}/users/${memberId}`, { + headers: { + Authorization: `Bearer ${localStorage.getItem("token")}`, + }, + } + ); if (res.ok) { return res.json(); } else { @@ -182,6 +280,7 @@ export const loginUser = async (credentials: { method: "POST", headers: { "Content-Type": "application/json", + Authorization: `Bearer ${localStorage.getItem("token")}`, }, body: JSON.stringify(credentials), }); diff --git a/frontend/lib/posts.tsx b/frontend/lib/posts.tsx index 2d9c096..cf91940 100644 --- a/frontend/lib/posts.tsx +++ b/frontend/lib/posts.tsx @@ -38,6 +38,7 @@ export const createUser = async (user: newUser) => { method: "POST", headers: { "Content-Type": "application/json", + Authorization: `Bearer ${localStorage.getItem("token")}`, }, body: JSON.stringify(user), }); @@ -59,6 +60,7 @@ export const loginUser = async (credentials: credentials) => { method: "POST", headers: { "Content-Type": "application/json", + Authorization: `Bearer ${localStorage.getItem("token")}`, }, body: JSON.stringify(credentials), }); From 507ce67274a7ca7531aa5f97d1ecf1780f4eb813 Mon Sep 17 00:00:00 2001 From: Jason Date: Fri, 31 May 2024 12:44:12 -0700 Subject: [PATCH 2/4] fix: merge conflicts --- frontend/lib/fetches.tsx | 51 ++++++---------------------------------- 1 file changed, 7 insertions(+), 44 deletions(-) diff --git a/frontend/lib/fetches.tsx b/frontend/lib/fetches.tsx index 62e0810..a669e1f 100644 --- a/frontend/lib/fetches.tsx +++ b/frontend/lib/fetches.tsx @@ -6,14 +6,7 @@ import { ObjectId } from "mongoose"; const vite_backend_url = import.meta.env.VITE_BACKEND_URL as string; export const fetchBasket = async (basketId: string) => { -<<<<<<< Updated upstream - return fetch(`${vite_backend_url}/baskets/${basketId}`); -}; - -export const fetchItem = async (itemId: string) => { - return fetch(`${vite_backend_url}/items/${itemId}`); -======= - return fetch(`http://localhost:3001/baskets/${basketId}`, { + return fetch(`${vite_backend_url}/baskets/${basketId}`, { headers: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, @@ -22,27 +15,22 @@ export const fetchItem = async (itemId: string) => { }; export const fetchItem = async (itemId: string) => { - return fetch(`http://localhost:3001/items/${itemId}`, { + return fetch(`${vite_backend_url}/items/${itemId}`, { headers: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, } ); ->>>>>>> Stashed changes }; export const fetchGroupById = async (groupId: string) => { try { -<<<<<<< Updated upstream - const res = await fetch(`${vite_backend_url}/groups/${groupId}`); -======= - const res = await fetch(`http://localhost:3001/groups/${groupId}`, { + const res = await fetch(`${vite_backend_url}/groups/${groupId}`, { headers: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, } ); ->>>>>>> Stashed changes if (res.ok) { return res.json(); } else { @@ -54,43 +42,26 @@ export const fetchGroupById = async (groupId: string) => { }; export const fetchUser = async (userId: ObjectId) => { -<<<<<<< Updated upstream - return fetch(`${vite_backend_url}/users/${userId}`); -}; - -export const fetchUserWithString = async (userId: string) => { return fetch(`${vite_backend_url}/users/${userId}`); -======= - return fetch(`http://localhost:3001/users/${userId}`, { - headers: { - Authorization: `Bearer ${localStorage.getItem("token")}`, - }, - } - ); }; export const fetchUserWithString = async (userId: string) => { - return fetch(`http://localhost:3001/users/${userId}`, { + return fetch(`${vite_backend_url}/users/${userId}`, { headers: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, } ); ->>>>>>> Stashed changes }; export const fetchUserGroupsByUser = async (user: IUser) => { const groupPromises = user.groups.map(async (group: ObjectId) => { -<<<<<<< Updated upstream - const res = await fetch(`${vite_backend_url}/groups/${group}`); -======= - const res = await fetch(`http://localhost:3001/groups/${group}`, { + const res = await fetch(`${vite_backend_url}/groups/${group}`, { headers: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, } ); ->>>>>>> Stashed changes if (res.status === 200) { const data = await res.json(); return data; @@ -103,16 +74,12 @@ export const fetchUserGroupsByUser = async (user: IUser) => { export const fetchUserFriendsByUser = async (user: IUser) => { const friendPromises = user.friends.map(async (friend: ObjectId) => { -<<<<<<< Updated upstream - const res = await fetch(`${vite_backend_url}/users/${friend}`); -======= - const res = await fetch(`http://localhost:3001/users/${friend}`, { + const res = await fetch(`${vite_backend_url}/users/${friend}`, { headers: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, } ); ->>>>>>> Stashed changes if (res.status === 200) { const data = await res.json(); return data; @@ -125,16 +92,12 @@ export const fetchUserFriendsByUser = async (user: IUser) => { export const addFriendToGroup = async (friendId: string, groupId: string) => { try { -<<<<<<< Updated upstream - const res = await fetch(`${vite_backend_url}/users/${friendId}`); -======= - const res = await fetch(`http://localhost:3001/users/${friendId}`, { + const res = await fetch(`${vite_backend_url}/users/${friendId}`, { headers: { Authorization: `Bearer ${localStorage.getItem("token")}`, }, } ); ->>>>>>> Stashed changes let friend; if (res.ok) { From 3a33d2ad0c5f9b4154a60a238c8ccf76f6910a89 Mon Sep 17 00:00:00 2001 From: Jason Date: Sat, 1 Jun 2024 23:30:27 -0700 Subject: [PATCH 3/4] feat: enforces user auth on backend --- backend/routes/basketRoutes.ts | 12 ++++++------ backend/routes/groupRoutes.ts | 11 ++++++----- backend/routes/itemRoutes.ts | 11 ++++++----- backend/routes/userRoutes.ts | 10 +++++----- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/backend/routes/basketRoutes.ts b/backend/routes/basketRoutes.ts index 2a1a02d..6cb4922 100644 --- a/backend/routes/basketRoutes.ts +++ b/backend/routes/basketRoutes.ts @@ -2,11 +2,11 @@ import express from "express"; import { Request, Response } from "express"; import Basket, { IBasket } from "../models/basketSchema"; import connectDB from "../connection"; -import { ObjectId } from "mongoose"; +import { authenticateUser } from "../auth"; const router = express.Router(); -router.get("/", async (req: Request, res: Response) => { +router.get("/", authenticateUser, async (req: Request, res: Response) => { connectDB(); try { const baskets = await Basket.find({}); @@ -20,7 +20,7 @@ router.get("/", async (req: Request, res: Response) => { } }); -router.get("/:basketid", async (req: Request, res: Response) => { +router.get("/:basketid", authenticateUser, async (req: Request, res: Response) => { // Ensure the database connection connectDB(); @@ -52,7 +52,7 @@ router.get("/:basketid", async (req: Request, res: Response) => { } }); -router.post("/", async (req: Request, res: Response) => { +router.post("/", authenticateUser, async (req: Request, res: Response) => { connectDB(); try { console.log("Creating a new basket with data:", req.body); @@ -79,7 +79,7 @@ router.post("/", async (req: Request, res: Response) => { } }); -router.patch("/:id", async (req: Request, res: Response) => { +router.patch("/:id", authenticateUser, async (req: Request, res: Response) => { // Get basket ID from URL const { id } = req.params; const updatedData: Partial = req.body; // Not a full update, only partial @@ -102,7 +102,7 @@ router.patch("/:id", async (req: Request, res: Response) => { } }); -router.delete("/:id", async (req: Request, res: Response) => { +router.delete("/:id", authenticateUser, async (req: Request, res: Response) => { connectDB(); const { id } = req.params; try { diff --git a/backend/routes/groupRoutes.ts b/backend/routes/groupRoutes.ts index f148aae..d2eeeef 100644 --- a/backend/routes/groupRoutes.ts +++ b/backend/routes/groupRoutes.ts @@ -1,11 +1,12 @@ import express from "express"; import { Request, Response } from "express"; import Group, { IGroup } from "../models/groupSchema"; +import { authenticateUser } from "../auth"; import connectDB from "../connection"; const router = express.Router(); -router.get("/", async (req: Request, res: Response) => { +router.get("/", authenticateUser, async (req: Request, res: Response) => { connectDB(); try { const users = await Group.find({}); @@ -19,7 +20,7 @@ router.get("/", async (req: Request, res: Response) => { } }); -router.get("/:groupid", async (req: Request, res: Response) => { +router.get("/:groupid", authenticateUser, async (req: Request, res: Response) => { // Ensure the database connection connectDB(); @@ -54,7 +55,7 @@ router.get("/:groupid", async (req: Request, res: Response) => { } }); -router.post("/", async (req: Request, res: Response) => { +router.post("/", authenticateUser, async (req: Request, res: Response) => { connectDB(); try { console.log("Creating a new group with data:", req.body); @@ -85,7 +86,7 @@ router.post("/", async (req: Request, res: Response) => { } }); -router.patch("/:id", async (req: Request, res: Response) => { +router.patch("/:id", authenticateUser, async (req: Request, res: Response) => { // Get user ID from URL const { id } = req.params; const updatedData: Partial = req.body; //Not a full update only partial @@ -108,7 +109,7 @@ router.patch("/:id", async (req: Request, res: Response) => { } }); -router.delete("/:id", async (req: Request, res: Response) => { +router.delete("/:id", authenticateUser, async (req: Request, res: Response) => { connectDB(); const { id } = req.params; try { diff --git a/backend/routes/itemRoutes.ts b/backend/routes/itemRoutes.ts index a9c71bf..7246139 100644 --- a/backend/routes/itemRoutes.ts +++ b/backend/routes/itemRoutes.ts @@ -1,11 +1,12 @@ import express from "express"; import { Request, Response } from "express"; import Item, { IItem } from "../models/itemSchema"; +import { authenticateUser } from "../auth"; import connectDB from "../connection"; const router = express.Router(); -router.get("/", async (req: Request, res: Response) => { +router.get("/", authenticateUser, async (req: Request, res: Response) => { connectDB(); try { const users = await Item.find({}); @@ -19,7 +20,7 @@ router.get("/", async (req: Request, res: Response) => { } }); -router.get("/:itemid", async (req: Request, res: Response) => { +router.get("/:itemid", authenticateUser, async (req: Request, res: Response) => { // Ensure the database connection connectDB(); @@ -55,7 +56,7 @@ router.get("/:itemid", async (req: Request, res: Response) => { } }); -router.post("/", async (req: Request, res: Response) => { +router.post("/", authenticateUser, async (req: Request, res: Response) => { connectDB(); try { console.log("Creating a new item with data:", req.body); @@ -93,7 +94,7 @@ router.post("/", async (req: Request, res: Response) => { } }); -router.patch("/:id", async (req: Request, res: Response) => { +router.patch("/:id", authenticateUser, async (req: Request, res: Response) => { // Get user ID from URL const { id } = req.params; const updatedData: Partial = req.body; //Not a full update only partial @@ -116,7 +117,7 @@ router.patch("/:id", async (req: Request, res: Response) => { } }); -router.delete("/:id", async (req: Request, res: Response) => { +router.delete("/:id", authenticateUser, async (req: Request, res: Response) => { connectDB(); const { id } = req.params; try { diff --git a/backend/routes/userRoutes.ts b/backend/routes/userRoutes.ts index 4e898f1..445d34d 100644 --- a/backend/routes/userRoutes.ts +++ b/backend/routes/userRoutes.ts @@ -7,7 +7,7 @@ import bcrypt from "bcrypt"; import mongoose from "mongoose"; const router = express.Router(); -router.get("/", async (req: Request, res: Response) => { +router.get("/", authenticateUser, async (req: Request, res: Response) => { connectDB(); try { @@ -22,7 +22,7 @@ router.get("/", async (req: Request, res: Response) => { } }); -router.get("/:userid", async (req: Request, res: Response) => { +router.get("/:userid", authenticateUser, async (req: Request, res: Response) => { // Ensure the database connection connectDB(); @@ -108,7 +108,7 @@ router.post("/", async (req: Request, res: Response) => { } }); -router.patch("/:id", async (req: Request, res: Response) => { +router.patch("/:id", authenticateUser, async (req: Request, res: Response) => { connectDB(); // Get user ID from URL const { id } = req.params; @@ -131,7 +131,7 @@ router.patch("/:id", async (req: Request, res: Response) => { } }); -router.delete("/:id", async (req: Request, res: Response) => { +router.delete("/:id", authenticateUser, async (req: Request, res: Response) => { connectDB(); const { id } = req.params; @@ -149,7 +149,7 @@ router.delete("/:id", async (req: Request, res: Response) => { } }); -router.delete("/:id/remove-friend", async (req: Request, res: Response) => { +router.delete("/:id/remove-friend", authenticateUser, async (req: Request, res: Response) => { connectDB(); const userId = req.params.id; const { friendId } = req.body; // Expecting friendId in the request body From fd6c6d0799ccbf15683bf8df31479ca755b6fed0 Mon Sep 17 00:00:00 2001 From: Jason Date: Sun, 2 Jun 2024 00:08:31 -0700 Subject: [PATCH 4/4] 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 (