From b98d107dc39515a8037e0eead33065f0505ad751 Mon Sep 17 00:00:00 2001 From: Aaron Ahmadyar Date: Wed, 23 Aug 2023 19:59:25 -0700 Subject: [PATCH 01/15] express-router --- backend/backend.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/backend/backend.js b/backend/backend.js index d90cf1e..c81ce33 100644 --- a/backend/backend.js +++ b/backend/backend.js @@ -16,8 +16,8 @@ dotenv.config(); // require mongoose const mongoose = require("mongoose"); +//connect to remote DB mongoose.set("debug", process.env.DEBUG); - mongoose .connect( "mongodb+srv://" + @@ -38,7 +38,6 @@ mongoose ) .catch((error) => console.log(error)); -console.log("Connected to MongoDB."); // -------------------------------------- // Services From b078f872ade63caa43117c4552f011f740daca97 Mon Sep 17 00:00:00 2001 From: Aaron Ahmadyar Date: Wed, 23 Aug 2023 20:11:25 -0700 Subject: [PATCH 02/15] login/register routes moved --- backend/backend.js | 47 -------------------------- backend/routes/authRoutes.js | 53 ++++++++++++++++++++++++++++++ backend/routes/ingredientRoutes.js | 0 backend/routes/recipeRoutes.js | 0 backend/routes/userRoutes.js | 0 5 files changed, 53 insertions(+), 47 deletions(-) create mode 100644 backend/routes/authRoutes.js create mode 100644 backend/routes/ingredientRoutes.js create mode 100644 backend/routes/recipeRoutes.js create mode 100644 backend/routes/userRoutes.js diff --git a/backend/backend.js b/backend/backend.js index c81ce33..d74805c 100644 --- a/backend/backend.js +++ b/backend/backend.js @@ -87,53 +87,6 @@ async function authenticateToken(req, res, next) { } } -// -------------------------------------------------- -// AUTHENTICATION ENDPOINTS -// -------------------------------------------------- -// login endpoint: -// get username and password from request body and pass to -// userServices.login() which authenticates the user from -// the database -app.post("/login", async (req, res) => { - const user = req.body; - try { - const result = await userServices.login(user.email, user.password); - - if (result === undefined || result.length === 0) { - res.status(404).send("Resource not found."); - } else { - const token = generateAccessToken({ id: result._id }); - res.status(201).json({ token: token }); - //res.send({ users_list: result }); - } - } catch (error) { - console.log(error); - res.status(500).send("Internal Server Error."); - } -}); - -// register endpoint: -// get username and password from request body and pass to -// userServices.register() which adds the user to the database -// after using bcrypt to hash the password -app.post("/register", async (req, res) => { - try { - const user = req.body; - const result = await userServices.register(user.email, user.password); - - if (result === undefined || result.length === 0) { - res.status(404).send("Resource not found."); - } else { - const token = generateAccessToken({ id: result._id }); - res.json({ token: token }).status(201); - //res.send({ users_list: result}); - } - } catch (error) { - console.log(error); - res.status(500).send("Internal Server Error."); - } -}); - // -------------------------------------------------- // USER ENDPOINTS // -------------------------------------------------- diff --git a/backend/routes/authRoutes.js b/backend/routes/authRoutes.js new file mode 100644 index 0000000..2731d20 --- /dev/null +++ b/backend/routes/authRoutes.js @@ -0,0 +1,53 @@ +const express = require("express"); +const router = express.Router(); + + + + +// -------------------------------------------------- +// AUTHENTICATION ENDPOINTS +// -------------------------------------------------- +// login endpoint: +// get username and password from request body and pass to +// userServices.login() which authenticates the user from +// the database +router.post("/login", async (req, res) => { + const user = req.body; + try { + const result = await userServices.login(user.email, user.password); + + if (result === undefined || result.length === 0) { + res.status(404).send("Resource not found."); + } else { + const token = generateAccessToken({ id: result._id }); + res.status(201).json({ token: token }); + //res.send({ users_list: result }); + } + } catch (error) { + console.log(error); + res.status(500).send("Internal Server Error."); + } +}); + +// register endpoint: +// get username and password from request body and pass to +// userServices.register() which adds the user to the database +// after using bcrypt to hash the password +router.post("/register", async (req, res) => { + try { + const user = req.body; + const result = await userServices.register(user.email, user.password); + + if (result === undefined || result.length === 0) { + res.status(404).send("Resource not found."); + } else { + const token = generateAccessToken({ id: result._id }); + res.json({ token: token }).status(201); + //res.send({ users_list: result}); + } + } catch (error) { + console.log(error); + res.status(500).send("Internal Server Error."); + } +}); + diff --git a/backend/routes/ingredientRoutes.js b/backend/routes/ingredientRoutes.js new file mode 100644 index 0000000..e69de29 diff --git a/backend/routes/recipeRoutes.js b/backend/routes/recipeRoutes.js new file mode 100644 index 0000000..e69de29 diff --git a/backend/routes/userRoutes.js b/backend/routes/userRoutes.js new file mode 100644 index 0000000..e69de29 From 20d96b963f868b61bf69bc08c22967944d5396a1 Mon Sep 17 00:00:00 2001 From: Aaron Ahmadyar Date: Wed, 23 Aug 2023 20:39:34 -0700 Subject: [PATCH 03/15] login/register functioning --- backend/backend.js | 14 +++++++++++++- backend/routes/authRoutes.js | 3 ++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/backend/backend.js b/backend/backend.js index d74805c..6cc2756 100644 --- a/backend/backend.js +++ b/backend/backend.js @@ -39,11 +39,19 @@ mongoose .catch((error) => console.log(error)); +//import routes +const authRoutes = require("./routes/authRoutes") +const userRoutes = require("./routes/authRoutes") +const ingredientRoutes = require("./routes/authRoutes") +const recipeRoutes = require("./routes/authRoutes") + + // -------------------------------------- // Services // -------------------------------------- // Spoonacular API const recipeAPI = require("./recipeAPI.js"); + // MongoDB / Mongoose const userServices = require("./controllers/user-services"); const recipeServices = require("./controllers/recipe-services"); @@ -58,10 +66,14 @@ app.get("/", (req, res) => { res.send("Hello World!"); }); -// designate protected routes +// auth middleware for protected routes app.use("/recipes", authenticateToken); app.use("/ingredients", authenticateToken); + +//imported routes +app.use("/", authRoutes); + // -------------------------------------- // Token // -------------------------------------- diff --git a/backend/routes/authRoutes.js b/backend/routes/authRoutes.js index 2731d20..8119bd8 100644 --- a/backend/routes/authRoutes.js +++ b/backend/routes/authRoutes.js @@ -3,7 +3,6 @@ const router = express.Router(); - // -------------------------------------------------- // AUTHENTICATION ENDPOINTS // -------------------------------------------------- @@ -51,3 +50,5 @@ router.post("/register", async (req, res) => { } }); + +module.exports = router; \ No newline at end of file From 615df10b750cc295b6308ec4b4e3f01b292e5a42 Mon Sep 17 00:00:00 2001 From: Aaron Ahmadyar Date: Wed, 23 Aug 2023 20:42:42 -0700 Subject: [PATCH 04/15] Small refactor --- backend/backend.js | 4 +--- backend/routes/authRoutes.js | 10 ++++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/backend/backend.js b/backend/backend.js index 6cc2756..7211302 100644 --- a/backend/backend.js +++ b/backend/backend.js @@ -77,9 +77,7 @@ app.use("/", authRoutes); // -------------------------------------- // Token // -------------------------------------- -function generateAccessToken(id) { - return jwt.sign(id, process.env.TOKEN_SECRET, { expiresIn: "1h" }); -} + //use case //app.get(..., authenticateToken, function (req, res) => ...); diff --git a/backend/routes/authRoutes.js b/backend/routes/authRoutes.js index 8119bd8..1d047e0 100644 --- a/backend/routes/authRoutes.js +++ b/backend/routes/authRoutes.js @@ -3,6 +3,16 @@ const router = express.Router(); + +function generateAccessToken(id) { + /* + Generates JWT + :param id: user DB ._id + :return: JWT token + */ + return jwt.sign(id, process.env.TOKEN_SECRET, { expiresIn: "1h" }); +} + // -------------------------------------------------- // AUTHENTICATION ENDPOINTS // -------------------------------------------------- From d64e4caac7d05ab13cd516577901ae50e3fadf94 Mon Sep 17 00:00:00 2001 From: Aaron Ahmadyar Date: Wed, 23 Aug 2023 20:44:48 -0700 Subject: [PATCH 05/15] Moved user routes --- backend/routes/userRoutes.js | 54 ++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/backend/routes/userRoutes.js b/backend/routes/userRoutes.js index e69de29..1c88ffc 100644 --- a/backend/routes/userRoutes.js +++ b/backend/routes/userRoutes.js @@ -0,0 +1,54 @@ +const express = require("express"); +const router = express.Router(); + + +// -------------------------------------------------- +// USER ENDPOINTS +// -------------------------------------------------- +// Get users endpoint: +router.get("/users", async (req, res) => { + const name = req.query["name"]; + try { + const result = await userServices.getUsers(name); + res.send({ users_list: result }); // can be empty array (no error if nothing found) + } catch (error) { + console.log(error); + res.status(500).send("Internal Server Error."); + } +}); + +// Get User by Id endpoint: +router.get("/users/:id", async (req, res) => { + const id = req.params.id; + try { + const result = await userServices.findUserById(id); + if (result === undefined || result.length === 0) { + res.status(404).send("Resource not found."); + } else { + res.send({ users_list: result }); + } + } catch (error) { + console.log(error); + res.status(500).send("Internal Server Error."); + } +}); + +// Add a Recipe to a User's Saved Recipes endpoint: +// - body of the request to this endpoint contains 1 field: recipe_id +router.post("/users/:id/recipes", async (req, res) => { + const user_id = req.params.id; + const user = await userServices.findUserById(user_id); + const recipe_id = req.body.recipe_id; + try { + const result = await userServices.addRecipe(user, recipe_id); + if (result === undefined || result.length === 0) { + res.status(404).send("Resource not found."); + } else { + res.send({ users_list: result }); + } + } catch (error) { + console.log(error); + res.status(500).send("Internal Server Error."); + } +}); + From f3c218b637c3c1f5232787a8e350f93ea1863aa6 Mon Sep 17 00:00:00 2001 From: Aaron Ahmadyar Date: Wed, 23 Aug 2023 20:52:37 -0700 Subject: [PATCH 06/15] user routes complete --- backend/backend.js | 67 +----------------------------------- backend/routes/userRoutes.js | 29 ++++++++++++---- 2 files changed, 24 insertions(+), 72 deletions(-) diff --git a/backend/backend.js b/backend/backend.js index 7211302..c02c1ec 100644 --- a/backend/backend.js +++ b/backend/backend.js @@ -73,6 +73,7 @@ app.use("/ingredients", authenticateToken); //imported routes app.use("/", authRoutes); +app.use("/users", userRoutes) // -------------------------------------- // Token @@ -97,56 +98,6 @@ async function authenticateToken(req, res, next) { } } -// -------------------------------------------------- -// USER ENDPOINTS -// -------------------------------------------------- -// Get users endpoint: -app.get("/users", async (req, res) => { - const name = req.query["name"]; - try { - const result = await userServices.getUsers(name); - res.send({ users_list: result }); // can be empty array (no error if nothing found) - } catch (error) { - console.log(error); - res.status(500).send("Internal Server Error."); - } -}); - -// Get User by Id endpoint: -app.get("/users/:id", async (req, res) => { - const id = req.params.id; - try { - const result = await userServices.findUserById(id); - if (result === undefined || result.length === 0) { - res.status(404).send("Resource not found."); - } else { - res.send({ users_list: result }); - } - } catch (error) { - console.log(error); - res.status(500).send("Internal Server Error."); - } -}); - -// Add a Recipe to a User's Saved Recipes endpoint: -// - body of the request to this endpoint contains 1 field: recipe_id -app.post("/users/:id/recipes", async (req, res) => { - const user_id = req.params.id; - const user = await userServices.findUserById(user_id); - const recipe_id = req.body.recipe_id; - try { - const result = await userServices.addRecipe(user, recipe_id); - if (result === undefined || result.length === 0) { - res.status(404).send("Resource not found."); - } else { - res.send({ users_list: result }); - } - } catch (error) { - console.log(error); - res.status(500).send("Internal Server Error."); - } -}); - app.delete("/recipes/:id", async (req, res) => { try { const recipe_id = req.params.id; @@ -163,22 +114,6 @@ app.delete("/recipes/:id", async (req, res) => { } }); -// Populate the Recipes for a specific User -app.get("/users/:id/recipes", async (req, res) => { - const user_id = req.params.id; - try { - const user = await userServices.findUserById(user_id); - const result = await userServices.getRecipes(user); - if (result === undefined || result.length === 0) { - res.status(404).send("Resource not found."); - } else { - res.send({ users_list: result }); - } - } catch (error) { - console.log(error); - res.status(500).send("Internal Server Error."); - } -}); //load in saved recipes app.get("/recipes", async (req, res) => { diff --git a/backend/routes/userRoutes.js b/backend/routes/userRoutes.js index 1c88ffc..68bde87 100644 --- a/backend/routes/userRoutes.js +++ b/backend/routes/userRoutes.js @@ -1,12 +1,10 @@ const express = require("express"); const router = express.Router(); - - // -------------------------------------------------- // USER ENDPOINTS // -------------------------------------------------- // Get users endpoint: -router.get("/users", async (req, res) => { +router.get("/", async (req, res) => { const name = req.query["name"]; try { const result = await userServices.getUsers(name); @@ -18,7 +16,7 @@ router.get("/users", async (req, res) => { }); // Get User by Id endpoint: -router.get("/users/:id", async (req, res) => { +router.get("/:id", async (req, res) => { const id = req.params.id; try { const result = await userServices.findUserById(id); @@ -33,9 +31,29 @@ router.get("/users/:id", async (req, res) => { } }); + + +// Populate the Recipes for a specific User +router.get("/:id/recipes", async (req, res) => { + const user_id = req.params.id; + try { + const user = await userServices.findUserById(user_id); + const result = await userServices.getRecipes(user); + if (result === undefined || result.length === 0) { + res.status(404).send("Resource not found."); + } else { + res.send({ users_list: result }); + } + } catch (error) { + console.log(error); + res.status(500).send("Internal Server Error."); + } +}); + + // Add a Recipe to a User's Saved Recipes endpoint: // - body of the request to this endpoint contains 1 field: recipe_id -router.post("/users/:id/recipes", async (req, res) => { +router.post("/:id/recipes", async (req, res) => { const user_id = req.params.id; const user = await userServices.findUserById(user_id); const recipe_id = req.body.recipe_id; @@ -51,4 +69,3 @@ router.post("/users/:id/recipes", async (req, res) => { res.status(500).send("Internal Server Error."); } }); - From 7d4fd6a1836a8ed7a3c2316bf75f2a4c91422539 Mon Sep 17 00:00:00 2001 From: Aaron Ahmadyar Date: Wed, 23 Aug 2023 20:57:20 -0700 Subject: [PATCH 07/15] recipe routes --- backend/backend.js | 144 +------------------------------- backend/routes/recipeRoutes.js | 147 +++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+), 143 deletions(-) diff --git a/backend/backend.js b/backend/backend.js index c02c1ec..ae28dd0 100644 --- a/backend/backend.js +++ b/backend/backend.js @@ -74,6 +74,7 @@ app.use("/ingredients", authenticateToken); //imported routes app.use("/", authRoutes); app.use("/users", userRoutes) +app.use("/recipes", recipeRoutes) // -------------------------------------- // Token @@ -98,149 +99,6 @@ async function authenticateToken(req, res, next) { } } -app.delete("/recipes/:id", async (req, res) => { - try { - const recipe_id = req.params.id; - const user_id = req._id; - const result = await userServices.removeRecipe(user_id, recipe_id); - if (!result) { - res.status(404).send("Resource not found."); - } else { - res.status(201).send({ users_list: result }); - } - } catch (error) { - console.log(error); - res.status(500).send("Internal Server Error."); - } -}); - - -//load in saved recipes -app.get("/recipes", async (req, res) => { - try { - //send back recipes associated with user - const id = req._id; - const recipes = await userServices.getRecipes(id); - if (recipes === undefined || recipes.length === 0) { - res.status(404).send("Recipes not Found for User"); - } else { - res.status(201).send(recipes).end(); - } - } catch (error) { - console.log(error); - res.status(505).send("Recipes not Found for User"); - } -}); - -// Get recipe by Id endpoint: -app.get("/recipes/:id", async (req, res) => { - const id = req.params.id; - try { - const result = await recipeServices.getRecipeByID(id); - console.log("GOT RESULT: ", result); - if (result === undefined || result.length === 0) { - res.status(404).send("Resource not found."); - } else { - res.send({ result }); - } - } catch (error) { - console.log(error); - res.status(500).send("Internal Server Error."); - } -}); - -//search API for recipes -app.post("/recipes", async (req, res) => { - try { - const id = req._id; - parameters = req.body; - recipes = await recipeAPI.getRecipes(parameters); - - if (recipes === undefined || recipes.length === 0) { - res.status(404).send("Resource not found."); - } else { - //check if recipe already exists in DB - for (let i = 0; i < recipes.length; i++) { - let recipe = await recipeServices.getRecipeByWebID(recipes[i].id); - if (recipe) { - recipes[i] = recipe; - } else { - //add recipe to database - recipes[i] = await recipeServices.addRecipe(recipes[i]); - } - } - const favorites = await userServices.getRecipes(id); - res.status(201).send({ - favorites: favorites, - recipes_list: recipes, - }); - } - } catch (error) { - console.log("ERROR IN RECIPE POST"); - console.log(error); - res.status(500).send("BAD AUTH /services/recipes"); - } -}); - -//Favorite Recipe -app.patch("/recipes/:id", async (req, res) => { - try { - //data base id for user and recipe - const userID = req._id; - const recipeID = req.params["id"]; - const result = await userServices.addRecipe(userID, recipeID); - if (!result) { - res.status(500).end(); - } else { - res.status(201).end(); - } - } catch (error) { - console.log(error); - res.status(500); - } -}); - -//Get ratings for recipe -// - most of this functionality is handled in the frontend, -// this endpoint sends a json object of a recipe -app.get("/recipes/:id/ratings", async (req, res) => { - try { - //get recipe ID - const recipeID = req.params["id"]; - const ratings = await recipeServices.getRatings(recipeID); - - if (ratings === undefined) { - res.status(404).send("Resource not Found").end(); - } else { - res.status(201).send(ratings).end(); - } - } catch (error) { - console.log(error); - res.status(500); - } -}); - -//add rating to recipe -app.patch("/recipes/:id/ratings", async (req, res) => { - try { - //get recipeID and new rating to add to recipe - const recipeID = req.params["id"]; - const rating = req.body["rating"]; - - //add rating to recipe - const result = await recipeServices.addRating(recipeID, rating); - - if (!result) { - res.status(404).end(); - } else { - res.status(201).send(result).end(); - } - } catch (error) { - console.log(error); - res.status(500); - } -}); - // -------------------------------------------------- // INGREDIENT ENDPOINTS // -------------------------------------------------- diff --git a/backend/routes/recipeRoutes.js b/backend/routes/recipeRoutes.js index e69de29..940b9aa 100644 --- a/backend/routes/recipeRoutes.js +++ b/backend/routes/recipeRoutes.js @@ -0,0 +1,147 @@ +const express = require("express"); +const router = express.Router(); + + +router.delete("/:id", async (req, res) => { + try { + const recipe_id = req.params.id; + const user_id = req._id; + const result = await userServices.removeRecipe(user_id, recipe_id); + if (!result) { + res.status(404).send("Resource not found."); + } else { + res.status(201).send({ users_list: result }); + } + } catch (error) { + console.log(error); + res.status(500).send("Internal Server Error."); + } +}); + + +//load in saved recipes +router.get("/", async (req, res) => { + try { + //send back recipes associated with user + const id = req._id; + const recipes = await userServices.getRecipes(id); + if (recipes === undefined || recipes.length === 0) { + res.status(404).send("Recipes not Found for User"); + } else { + res.status(201).send(recipes).end(); + } + } catch (error) { + console.log(error); + res.status(505).send("Recipes not Found for User"); + } +}); + +// Get recipe by Id endpoint: +router.get("/:id", async (req, res) => { + const id = req.params.id; + try { + const result = await recipeServices.getRecipeByID(id); + console.log("GOT RESULT: ", result); + if (result === undefined || result.length === 0) { + res.status(404).send("Resource not found."); + } else { + res.send({ result }); + } + } catch (error) { + console.log(error); + res.status(500).send("Internal Server Error."); + } +}); + +//search API for recipes +router.post("/", async (req, res) => { + try { + const id = req._id; + parameters = req.body; + recipes = await recipeAPI.getRecipes(parameters); + + if (recipes === undefined || recipes.length === 0) { + res.status(404).send("Resource not found."); + } else { + //check if recipe already exists in DB + for (let i = 0; i < recipes.length; i++) { + let recipe = await recipeServices.getRecipeByWebID(recipes[i].id); + if (recipe) { + recipes[i] = recipe; + } else { + //add recipe to database + recipes[i] = await recipeServices.addRecipe(recipes[i]); + } + } + const favorites = await userServices.getRecipes(id); + res.status(201).send({ + favorites: favorites, + recipes_list: recipes, + }); + } + } catch (error) { + console.log("ERROR IN RECIPE POST"); + console.log(error); + res.status(500).send("BAD AUTH /services/recipes"); + } +}); + +//Favorite Recipe +router.patch("/:id", async (req, res) => { + try { + //data base id for user and recipe + const userID = req._id; + const recipeID = req.params["id"]; + const result = await userServices.addRecipe(userID, recipeID); + if (!result) { + res.status(500).end(); + } else { + res.status(201).end(); + } + } catch (error) { + console.log(error); + res.status(500); + } +}); + +//Get ratings for recipe +// - most of this functionality is handled in the frontend, +// this endpoint sends a json object of a recipe +router.get("/:id/ratings", async (req, res) => { + try { + //get recipe ID + const recipeID = req.params["id"]; + const ratings = await recipeServices.getRatings(recipeID); + + if (ratings === undefined) { + res.status(404).send("Resource not Found").end(); + } else { + res.status(201).send(ratings).end(); + } + } catch (error) { + console.log(error); + res.status(500); + } +}); + +//add rating to recipe +router.patch("/:id/ratings", async (req, res) => { + try { + //get recipeID and new rating to add to recipe + const recipeID = req.params["id"]; + const rating = req.body["rating"]; + + //add rating to recipe + const result = await recipeServices.addRating(recipeID, rating); + + if (!result) { + res.status(404).end(); + } else { + res.status(201).send(result).end(); + } + } catch (error) { + console.log(error); + res.status(500); + } +}); + From 5c3d2683de7d552acdf6c8ce4f36b9854d4f5f9f Mon Sep 17 00:00:00 2001 From: Aaron Ahmadyar Date: Wed, 23 Aug 2023 21:06:51 -0700 Subject: [PATCH 08/15] ingredient routes --- backend/backend.js | 46 ++-------------------------- backend/routes/ingredientRoutes.js | 48 ++++++++++++++++++++++++++++++ backend/routes/recipeRoutes.js | 2 ++ 3 files changed, 53 insertions(+), 43 deletions(-) diff --git a/backend/backend.js b/backend/backend.js index ae28dd0..29cd3ae 100644 --- a/backend/backend.js +++ b/backend/backend.js @@ -73,8 +73,9 @@ app.use("/ingredients", authenticateToken); //imported routes app.use("/", authRoutes); -app.use("/users", userRoutes) -app.use("/recipes", recipeRoutes) +app.use("/users", userRoutes); +app.use("/recipes", recipeRoutes); +app.use("/ingredients", ingredientRoutes); // -------------------------------------- // Token @@ -99,47 +100,6 @@ async function authenticateToken(req, res, next) { } } -// -------------------------------------------------- -// INGREDIENT ENDPOINTS -// -------------------------------------------------- -// Get all ingredients endpoint: - -//return ingredients associated with user -app.get("/ingredients", async (req, res) => { - try { - const id = req._id; - const result = await userServices.getIngredients(id); - if (result === undefined || result.length === 0) { - res.status(404).send("Resource not found."); - } else { - res.status(201).send({ ingredients_list: result }); // can be empty array (no error if nothing found) - } - } catch (error) { - console.log(error); - res.status(500).send("Internal Server Error."); - } -}); - -// Create ingredient endpoint: -app.put("/ingredients", async (req, res) => { - const data = req.body; - try { - const id = req._id; - const updatedUser = await userServices.updateIngredients( - id, - data.ingredients - ); - - if (updatedUser) { - res.status(201).send(updatedUser).end(); - } else { - res.status(400).send("Bad Request."); - } - } catch (error) { - console.log(error); - res.status(500).send("Internal Server Error."); - } -}); // export mongoose connection module.exports = mongoose; diff --git a/backend/routes/ingredientRoutes.js b/backend/routes/ingredientRoutes.js index e69de29..93946ab 100644 --- a/backend/routes/ingredientRoutes.js +++ b/backend/routes/ingredientRoutes.js @@ -0,0 +1,48 @@ +const express = require("express"); +const router = express.Router(); + + +// -------------------------------------------------- +// INGREDIENT ENDPOINTS +// -------------------------------------------------- +// Get all ingredients endpoint: + +//return ingredients associated with user +router.get("/", async (req, res) => { + try { + const id = req._id; + const result = await userServices.getIngredients(id); + if (result === undefined || result.length === 0) { + res.status(404).send("Resource not found."); + } else { + res.status(201).send({ ingredients_list: result }); // can be empty array (no error if nothing found) + } + } catch (error) { + console.log(error); + res.status(500).send("Internal Server Error."); + } +}); + +// Create ingredient endpoint: +router.put("/", async (req, res) => { + const data = req.body; + try { + const id = req._id; + const updatedUser = await userServices.updateIngredients( + id, + data.ingredients + ); + + if (updatedUser) { + res.status(201).send(updatedUser).end(); + } else { + res.status(400).send("Bad Request."); + } + } catch (error) { + console.log(error); + res.status(500).send("Internal Server Error."); + } +}); + + +modules.exports = router; diff --git a/backend/routes/recipeRoutes.js b/backend/routes/recipeRoutes.js index 940b9aa..b87b7ec 100644 --- a/backend/routes/recipeRoutes.js +++ b/backend/routes/recipeRoutes.js @@ -145,3 +145,5 @@ router.patch("/:id/ratings", async (req, res) => { } }); + +module.exports = router; From 5b1df2fc4754fca086f935ebda3acdfd473a8c82 Mon Sep 17 00:00:00 2001 From: Aaron Ahmadyar Date: Wed, 23 Aug 2023 21:18:56 -0700 Subject: [PATCH 09/15] Router Complete --- backend/backend.js | 5 ++--- backend/routes/recipeRoutes.js | 1 - 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/backend/backend.js b/backend/backend.js index 29cd3ae..fc1cc6c 100644 --- a/backend/backend.js +++ b/backend/backend.js @@ -77,14 +77,13 @@ app.use("/users", userRoutes); app.use("/recipes", recipeRoutes); app.use("/ingredients", ingredientRoutes); + // -------------------------------------- // Token // -------------------------------------- - - //use case //app.get(..., authenticateToken, function (req, res) => ...); -//middleware to authenticate token, used for /services and all nested paths +//middleware to authenticate token, used for protected routes async function authenticateToken(req, res, next) { token = req.headers["token"]; // if token is null return a response with status 401 and end the request diff --git a/backend/routes/recipeRoutes.js b/backend/routes/recipeRoutes.js index b87b7ec..ec896a8 100644 --- a/backend/routes/recipeRoutes.js +++ b/backend/routes/recipeRoutes.js @@ -41,7 +41,6 @@ router.get("/:id", async (req, res) => { const id = req.params.id; try { const result = await recipeServices.getRecipeByID(id); - console.log("GOT RESULT: ", result); if (result === undefined || result.length === 0) { res.status(404).send("Resource not found."); } else { From ee89bc861feb3286519b8a5644b853003629c51e Mon Sep 17 00:00:00 2001 From: Aaron Ahmadyar Date: Thu, 24 Aug 2023 13:15:49 -0700 Subject: [PATCH 10/15] Updated authenticate token for bearer --- backend/backend.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/backend.js b/backend/backend.js index fc1cc6c..a0f2d45 100644 --- a/backend/backend.js +++ b/backend/backend.js @@ -85,11 +85,11 @@ app.use("/ingredients", ingredientRoutes); //app.get(..., authenticateToken, function (req, res) => ...); //middleware to authenticate token, used for protected routes async function authenticateToken(req, res, next) { - token = req.headers["token"]; + token = req.headers.Authorization; // if token is null return a response with status 401 and end the request if (token == null) res.status(401).send("Unauthorized"); else { - jwt.verify(token, process.env.TOKEN_SECRET, (err, user) => { + jwt.verify(token.split(' ')[1], process.env.TOKEN_SECRET, (err, user) => { if (err) res.status(403).send("Forbidden"); else { req._id = user.id; From bdebc1756c891977c5617bc2597276b326dcd02a Mon Sep 17 00:00:00 2001 From: Aaron Ahmadyar Date: Fri, 25 Aug 2023 19:40:27 -0700 Subject: [PATCH 11/15] Still issues with router Backend URL was requesting azure previously not local host whlie testing --- backend/backend.js | 71 ++++++------------- backend/package-lock.json | 21 ++++++ backend/package.json | 1 + backend/routes/authRoutes.js | 8 ++- backend/routes/ingredientRoutes.js | 3 + backend/routes/recipeRoutes.js | 3 + backend/routes/userRoutes.js | 6 ++ backend/yarn.lock | 18 +++-- .../src/components/context/AuthProvider.js | 4 +- react-frontend/src/pages/login_form.js | 1 + 10 files changed, 79 insertions(+), 57 deletions(-) diff --git a/backend/backend.js b/backend/backend.js index a0f2d45..fd7a387 100644 --- a/backend/backend.js +++ b/backend/backend.js @@ -1,7 +1,3 @@ -//https -const https = require("https"); -const fs = require("fs"); - // express js & cors middleware const express = require("express"); const cors = require("cors"); @@ -9,13 +5,25 @@ const cors = require("cors"); //web token for user auth const jwt = require("jsonwebtoken"); +const cookieParser = require("cookie-parser"); + // Using .env file for environment variables (DB connection) const dotenv = require("dotenv"); dotenv.config(); +//import routes +const authRoutes = require("./routes/authRoutes") +const userRoutes = require("./routes/authRoutes") +const ingredientRoutes = require("./routes/authRoutes") +const recipeRoutes = require("./routes/authRoutes") + +// Spoonacular API methods +const recipeAPI = require("./recipeAPI.js"); + // require mongoose const mongoose = require("mongoose"); + //connect to remote DB mongoose.set("debug", process.env.DEBUG); mongoose @@ -39,38 +47,23 @@ mongoose .catch((error) => console.log(error)); -//import routes -const authRoutes = require("./routes/authRoutes") -const userRoutes = require("./routes/authRoutes") -const ingredientRoutes = require("./routes/authRoutes") -const recipeRoutes = require("./routes/authRoutes") - - -// -------------------------------------- -// Services -// -------------------------------------- -// Spoonacular API -const recipeAPI = require("./recipeAPI.js"); - -// MongoDB / Mongoose -const userServices = require("./controllers/user-services"); -const recipeServices = require("./controllers/recipe-services"); +//express session const app = express(); const port = 8000; app.use(cors()); app.use(express.json()); - -app.get("/", (req, res) => { - res.send("Hello World!"); -}); +//app.use(cookieParser()); // auth middleware for protected routes app.use("/recipes", authenticateToken); app.use("/ingredients", authenticateToken); +//app.get("/", (req, res) => { +// res.send("Hello World!"); +//}); //imported routes app.use("/", authRoutes); app.use("/users", userRoutes); @@ -78,6 +71,8 @@ app.use("/recipes", recipeRoutes); app.use("/ingredients", ingredientRoutes); + + // -------------------------------------- // Token // -------------------------------------- @@ -85,11 +80,12 @@ app.use("/ingredients", ingredientRoutes); //app.get(..., authenticateToken, function (req, res) => ...); //middleware to authenticate token, used for protected routes async function authenticateToken(req, res, next) { - token = req.headers.Authorization; + //token = req.headers.Authorization.split(" ")[1]; + let token = req.headers['token']; // if token is null return a response with status 401 and end the request if (token == null) res.status(401).send("Unauthorized"); else { - jwt.verify(token.split(' ')[1], process.env.TOKEN_SECRET, (err, user) => { + jwt.verify(token, process.env.TOKEN_SECRET, (err, user) => { if (err) res.status(403).send("Forbidden"); else { req._id = user.id; @@ -112,26 +108,3 @@ app.listen(process.env.PORT || port, () => { } else console.log(`REST API is listening on: http://localhost:${port}.`); }); -/* -https - .createServer( - // Provide the private and public key to the server by reading each - // file's content with the readFileSync() method. - { - key: fs.readFileSync("certificates/key.pem"), - cert: fs.readFileSync("certificates/cert.pem"), - }, - app - ) - .listen(process.env.PORT || port, () => { - if (process.env.PORT) - console.log(`REST API is listening on: https://localhost:${process.env.PORT}`); - else - console.log(`REST API is listening on: http://localhost:${port}.`); -}); -*/ - -// recipeAPI.getRecipe( { -// "ingredients" : ["banana", "milk"], -// "maxCal" : 1500 -// }); diff --git a/backend/package-lock.json b/backend/package-lock.json index 3ec8d2a..82171f6 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "axios": "^1.4.0", "bcrypt": "^5.1.0", + "cookie-parser": "^1.4.6", "cores": "^0.8.0", "cors": "^2.8.5", "dotenv": "^16.0.3", @@ -1838,6 +1839,26 @@ "node": ">= 0.6" } }, + "node_modules/cookie-parser": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz", + "integrity": "sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA==", + "dependencies": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/cookie-parser/node_modules/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", diff --git a/backend/package.json b/backend/package.json index d347706..0c7612b 100644 --- a/backend/package.json +++ b/backend/package.json @@ -5,6 +5,7 @@ "dependencies": { "axios": "^1.4.0", "bcrypt": "^5.1.0", + "cookie-parser": "^1.4.6", "cores": "^0.8.0", "cors": "^2.8.5", "dotenv": "^16.0.3", diff --git a/backend/routes/authRoutes.js b/backend/routes/authRoutes.js index 1d047e0..7b7681f 100644 --- a/backend/routes/authRoutes.js +++ b/backend/routes/authRoutes.js @@ -1,7 +1,8 @@ const express = require("express"); const router = express.Router(); - +//DB models +const userServices = require("../controllers/user-services"); function generateAccessToken(id) { @@ -22,6 +23,7 @@ function generateAccessToken(id) { // the database router.post("/login", async (req, res) => { const user = req.body; + console.log(user); try { const result = await userServices.login(user.email, user.password); @@ -45,6 +47,7 @@ router.post("/login", async (req, res) => { router.post("/register", async (req, res) => { try { const user = req.body; + console.log(user); const result = await userServices.register(user.email, user.password); if (result === undefined || result.length === 0) { @@ -60,5 +63,8 @@ router.post("/register", async (req, res) => { } }); +router.get("/login", async (req, res) => { + res.send("

test

"); +}) module.exports = router; \ No newline at end of file diff --git a/backend/routes/ingredientRoutes.js b/backend/routes/ingredientRoutes.js index 93946ab..132e5b6 100644 --- a/backend/routes/ingredientRoutes.js +++ b/backend/routes/ingredientRoutes.js @@ -2,6 +2,9 @@ const express = require("express"); const router = express.Router(); +//DB models +const userServices = require("../controllers/user-services"); + // -------------------------------------------------- // INGREDIENT ENDPOINTS // -------------------------------------------------- diff --git a/backend/routes/recipeRoutes.js b/backend/routes/recipeRoutes.js index ec896a8..075a671 100644 --- a/backend/routes/recipeRoutes.js +++ b/backend/routes/recipeRoutes.js @@ -1,6 +1,9 @@ const express = require("express"); const router = express.Router(); +//DB models +const userServices = require("../controllers/user-services"); +const recipeServices = require("../controllers/recipe-services"); router.delete("/:id", async (req, res) => { try { diff --git a/backend/routes/userRoutes.js b/backend/routes/userRoutes.js index 68bde87..645110f 100644 --- a/backend/routes/userRoutes.js +++ b/backend/routes/userRoutes.js @@ -1,5 +1,11 @@ +//express router const express = require("express"); const router = express.Router(); + +//DB models +const userServices = require("../controllers/user-services"); + + // -------------------------------------------------- // USER ENDPOINTS // -------------------------------------------------- diff --git a/backend/yarn.lock b/backend/yarn.lock index c441234..32ca323 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -1095,11 +1095,24 @@ convert-source-map@^2.0.0: resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== +cookie-parser@^1.4.6: + version "1.4.6" + resolved "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.6.tgz" + integrity sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA== + dependencies: + cookie "0.4.1" + cookie-signature "1.0.6" + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== +cookie@0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + cookie@0.5.0: version "0.5.0" resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" @@ -1436,11 +1449,6 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@^2.3.2, fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - function-bind@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" diff --git a/react-frontend/src/components/context/AuthProvider.js b/react-frontend/src/components/context/AuthProvider.js index 1e62cea..bcfaf44 100644 --- a/react-frontend/src/components/context/AuthProvider.js +++ b/react-frontend/src/components/context/AuthProvider.js @@ -15,7 +15,7 @@ export const AuthProvider = ({ children }) => { const navigate = useNavigate(); const handleRegister = async (user) => { - const response = await axios.post(`https://cookmyfridge-backend.azurewebsites.net/register`, user); + const response = await axios.post(process.env.REACT_APP_BACKEND_URL, user); const token = response.data['token'] setToken(token); @@ -47,7 +47,7 @@ export const AuthProvider = ({ children }) => { console.log("In Login"); try{ - const response = await axios.post(`https://cookmyfridge-backend.azurewebsites.net/login`, user); + const response = await axios.post(process.env.REACT_APP_BACKEND_URL, user); if (response.status === 201){ const token = response.data['token']; setToken(token); diff --git a/react-frontend/src/pages/login_form.js b/react-frontend/src/pages/login_form.js index 9bc4be2..6964811 100644 --- a/react-frontend/src/pages/login_form.js +++ b/react-frontend/src/pages/login_form.js @@ -121,6 +121,7 @@ function LoginForm() { async function onSubmit(e) { e.preventDefault(); try { + console.log("USER", user); const c = await Auth.onLogin(user) if (c) { setBad("BAD PASSWORD"); From af3c2056150dfdbb121b1436645a3f1835f280bd Mon Sep 17 00:00:00 2001 From: Aaron Ahmadyar Date: Fri, 25 Aug 2023 20:43:35 -0700 Subject: [PATCH 12/15] router seems to work --- backend/backend.js | 10 +++++----- backend/routes/authRoutes.js | 2 +- backend/routes/ingredientRoutes.js | 2 +- backend/routes/recipeRoutes.js | 2 ++ backend/routes/userRoutes.js | 3 +++ react-frontend/src/components/context/AuthProvider.js | 4 ++-- 6 files changed, 14 insertions(+), 9 deletions(-) diff --git a/backend/backend.js b/backend/backend.js index fd7a387..3cfc21a 100644 --- a/backend/backend.js +++ b/backend/backend.js @@ -12,10 +12,10 @@ const dotenv = require("dotenv"); dotenv.config(); //import routes -const authRoutes = require("./routes/authRoutes") -const userRoutes = require("./routes/authRoutes") -const ingredientRoutes = require("./routes/authRoutes") -const recipeRoutes = require("./routes/authRoutes") +const authRoutes = require("./routes/authRoutes"); +const userRoutes = require("./routes/userRoutes"); +const ingredientRoutes = require("./routes/ingredientRoutes"); +const recipeRoutes = require("./routes/recipeRoutes"); // Spoonacular API methods const recipeAPI = require("./recipeAPI.js"); @@ -54,7 +54,7 @@ const port = 8000; app.use(cors()); app.use(express.json()); -//app.use(cookieParser()); +app.use(cookieParser()); // auth middleware for protected routes app.use("/recipes", authenticateToken); diff --git a/backend/routes/authRoutes.js b/backend/routes/authRoutes.js index 7b7681f..db4e669 100644 --- a/backend/routes/authRoutes.js +++ b/backend/routes/authRoutes.js @@ -4,6 +4,7 @@ const router = express.Router(); //DB models const userServices = require("../controllers/user-services"); +const jwt = require("jsonwebtoken"); function generateAccessToken(id) { /* @@ -23,7 +24,6 @@ function generateAccessToken(id) { // the database router.post("/login", async (req, res) => { const user = req.body; - console.log(user); try { const result = await userServices.login(user.email, user.password); diff --git a/backend/routes/ingredientRoutes.js b/backend/routes/ingredientRoutes.js index 132e5b6..84ac384 100644 --- a/backend/routes/ingredientRoutes.js +++ b/backend/routes/ingredientRoutes.js @@ -48,4 +48,4 @@ router.put("/", async (req, res) => { }); -modules.exports = router; +module.exports = router; diff --git a/backend/routes/recipeRoutes.js b/backend/routes/recipeRoutes.js index 075a671..1f25a4b 100644 --- a/backend/routes/recipeRoutes.js +++ b/backend/routes/recipeRoutes.js @@ -1,6 +1,8 @@ const express = require("express"); const router = express.Router(); +router.use(express.json()) + //DB models const userServices = require("../controllers/user-services"); const recipeServices = require("../controllers/recipe-services"); diff --git a/backend/routes/userRoutes.js b/backend/routes/userRoutes.js index 645110f..88562bb 100644 --- a/backend/routes/userRoutes.js +++ b/backend/routes/userRoutes.js @@ -4,6 +4,7 @@ const router = express.Router(); //DB models const userServices = require("../controllers/user-services"); +const { model } = require("mongoose"); // -------------------------------------------------- @@ -75,3 +76,5 @@ router.post("/:id/recipes", async (req, res) => { res.status(500).send("Internal Server Error."); } }); + +module.exports = router; diff --git a/react-frontend/src/components/context/AuthProvider.js b/react-frontend/src/components/context/AuthProvider.js index bcfaf44..da7de31 100644 --- a/react-frontend/src/components/context/AuthProvider.js +++ b/react-frontend/src/components/context/AuthProvider.js @@ -15,7 +15,7 @@ export const AuthProvider = ({ children }) => { const navigate = useNavigate(); const handleRegister = async (user) => { - const response = await axios.post(process.env.REACT_APP_BACKEND_URL, user); + const response = await axios.post(`${process.env.REACT_APP_BACKEND_URL}/register`, user); const token = response.data['token'] setToken(token); @@ -47,7 +47,7 @@ export const AuthProvider = ({ children }) => { console.log("In Login"); try{ - const response = await axios.post(process.env.REACT_APP_BACKEND_URL, user); + const response = await axios.post(`${process.env.REACT_APP_BACKEND_URL}/login`, user); if (response.status === 201){ const token = response.data['token']; setToken(token); From 039c85e190760417a4c6828bc27affe97238b37d Mon Sep 17 00:00:00 2001 From: Aaron Ahmadyar Date: Sat, 26 Aug 2023 00:17:48 -0700 Subject: [PATCH 13/15] Most features seem to be working --- backend/backend.js | 51 ++++--------------- backend/middleware.js | 22 ++++++++ backend/routes/authRoutes.js | 6 ++- backend/routes/recipeRoutes.js | 5 +- backend/routes/userRoutes.js | 1 - .../components/context/ingredients_context.js | 20 ++++---- 6 files changed, 47 insertions(+), 58 deletions(-) create mode 100644 backend/middleware.js diff --git a/backend/backend.js b/backend/backend.js index 3cfc21a..85f902f 100644 --- a/backend/backend.js +++ b/backend/backend.js @@ -2,28 +2,24 @@ const express = require("express"); const cors = require("cors"); -//web token for user auth -const jwt = require("jsonwebtoken"); - const cookieParser = require("cookie-parser"); // Using .env file for environment variables (DB connection) const dotenv = require("dotenv"); dotenv.config(); +//import middleware functions +const middleware = require("./middleware"); + //import routes const authRoutes = require("./routes/authRoutes"); const userRoutes = require("./routes/userRoutes"); const ingredientRoutes = require("./routes/ingredientRoutes"); const recipeRoutes = require("./routes/recipeRoutes"); -// Spoonacular API methods -const recipeAPI = require("./recipeAPI.js"); - // require mongoose const mongoose = require("mongoose"); - //connect to remote DB mongoose.set("debug", process.env.DEBUG); mongoose @@ -46,8 +42,6 @@ mongoose ) .catch((error) => console.log(error)); - - //express session const app = express(); const port = 8000; @@ -57,44 +51,18 @@ app.use(express.json()); app.use(cookieParser()); // auth middleware for protected routes -app.use("/recipes", authenticateToken); -app.use("/ingredients", authenticateToken); - +app.use("/recipes", middleware.authenticateToken); +app.use("/ingredients", middleware.authenticateToken); -//app.get("/", (req, res) => { -// res.send("Hello World!"); -//}); -//imported routes +//use routes defined by express router app.use("/", authRoutes); app.use("/users", userRoutes); app.use("/recipes", recipeRoutes); app.use("/ingredients", ingredientRoutes); - - - -// -------------------------------------- -// Token -// -------------------------------------- -//use case -//app.get(..., authenticateToken, function (req, res) => ...); -//middleware to authenticate token, used for protected routes -async function authenticateToken(req, res, next) { - //token = req.headers.Authorization.split(" ")[1]; - let token = req.headers['token']; - // if token is null return a response with status 401 and end the request - if (token == null) res.status(401).send("Unauthorized"); - else { - jwt.verify(token, process.env.TOKEN_SECRET, (err, user) => { - if (err) res.status(403).send("Forbidden"); - else { - req._id = user.id; - next(); - } - }); - } -} - +app.get("/", (req, res) => { + res.send("Hello World!"); +}); // export mongoose connection module.exports = mongoose; @@ -107,4 +75,3 @@ app.listen(process.env.PORT || port, () => { ); } else console.log(`REST API is listening on: http://localhost:${port}.`); }); - diff --git a/backend/middleware.js b/backend/middleware.js new file mode 100644 index 0000000..602280c --- /dev/null +++ b/backend/middleware.js @@ -0,0 +1,22 @@ +const jwt = require("jsonwebtoken"); + +//middleware to authenticate token, used for protected routes +async function authenticateToken(req, res, next) { + //let token = req.headers.Authorization.split(" ")[1]; + let token = req.headers["token"]; + // if token is null return a response with status 401 and end the request + if (token == null) res.status(401).send("Unauthorized"); + else { + jwt.verify(token, process.env.TOKEN_SECRET, (err, user) => { + if (err) res.status(403).send("Forbidden"); + else { + req._id = user.id; + next(); + } + }); + } +} + +module.exports = { + authenticateToken, +}; diff --git a/backend/routes/authRoutes.js b/backend/routes/authRoutes.js index db4e669..ac75381 100644 --- a/backend/routes/authRoutes.js +++ b/backend/routes/authRoutes.js @@ -4,6 +4,7 @@ const router = express.Router(); //DB models const userServices = require("../controllers/user-services"); +//JWT module const jwt = require("jsonwebtoken"); function generateAccessToken(id) { @@ -26,6 +27,7 @@ router.post("/login", async (req, res) => { const user = req.body; try { const result = await userServices.login(user.email, user.password); + console.log(result); if (result === undefined || result.length === 0) { res.status(404).send("Resource not found."); @@ -65,6 +67,6 @@ router.post("/register", async (req, res) => { router.get("/login", async (req, res) => { res.send("

test

"); -}) +}); -module.exports = router; \ No newline at end of file +module.exports = router; diff --git a/backend/routes/recipeRoutes.js b/backend/routes/recipeRoutes.js index 1f25a4b..3dfb7a2 100644 --- a/backend/routes/recipeRoutes.js +++ b/backend/routes/recipeRoutes.js @@ -1,7 +1,8 @@ const express = require("express"); const router = express.Router(); -router.use(express.json()) +// Spoonacular API methods +const recipeAPI = require("../recipeAPI.js"); //DB models const userServices = require("../controllers/user-services"); @@ -23,7 +24,6 @@ router.delete("/:id", async (req, res) => { } }); - //load in saved recipes router.get("/", async (req, res) => { try { @@ -149,5 +149,4 @@ router.patch("/:id/ratings", async (req, res) => { } }); - module.exports = router; diff --git a/backend/routes/userRoutes.js b/backend/routes/userRoutes.js index 88562bb..6909f61 100644 --- a/backend/routes/userRoutes.js +++ b/backend/routes/userRoutes.js @@ -4,7 +4,6 @@ const router = express.Router(); //DB models const userServices = require("../controllers/user-services"); -const { model } = require("mongoose"); // -------------------------------------------------- diff --git a/react-frontend/src/components/context/ingredients_context.js b/react-frontend/src/components/context/ingredients_context.js index 7848f26..9b98f09 100644 --- a/react-frontend/src/components/context/ingredients_context.js +++ b/react-frontend/src/components/context/ingredients_context.js @@ -22,7 +22,7 @@ export const IngredientProvider = ({ children }) => { const get_ratings = async (recipe_id, token) => { try { const tok = {headers: {'token': token}} - const response = await axios.get(`https://cookmyfridge-backend.azurewebsites.net/recipes/${recipe_id}/ratings`, tok); + const response = await axios.get(`${process.env.REACT_APP_BACKEND_URL}/recipes/${recipe_id}/ratings`, tok); setRatings(response.data.ratings); return response.data; @@ -34,7 +34,7 @@ export const IngredientProvider = ({ children }) => { const get_recipeById = async (recipe_id, token) => { try { const tok = {headers: {'token': token}}; - const response = await axios.get(`https://cookmyfridge-backend.azurewebsites.net/recipes/${recipe_id}`, tok); + const response = await axios.get(`${process.env.REACT_APP_BACKEND_URL}/${recipe_id}`, tok); return response.data; } catch (error) { @@ -45,7 +45,7 @@ export const IngredientProvider = ({ children }) => { const send_rating = async (recipe_id, rating, token) => { const tok = {headers: {'token': token}} try { - const response = await axios.patch(`https://cookmyfridge-backend.azurewebsites.net/recipes/${recipe_id}/ratings`, {'rating':rating}, tok); + const response = await axios.patch(`${process.env.REACT_APP_BACKEND_URL}/recipes/${recipe_id}/ratings`, {'rating':rating}, tok); setRatings(response.data['ratings']); } catch (error) { console.log(error); @@ -55,7 +55,7 @@ export const IngredientProvider = ({ children }) => { const send_recipe = async (recipe, token) => { const tok = {headers: {'token': token}}; try { - const response = await axios.post("https://cookmyfridge-backend.azurewebsites.net/recipes", recipe, tok); + const response = await axios.post(`${process.env.REACT_APP_BACKEND_URL}/recipes`, recipe, tok); const r = response.data['recipes_list']; let favorites = [] if (response.data['favorites'] === undefined) { @@ -89,7 +89,7 @@ export const IngredientProvider = ({ children }) => { const favorite_recipe = async (id, token) => { const tok = {headers: {'token': token}}; try { - const response = await axios.patch(`https://cookmyfridge-backend.azurewebsites.net/recipes/${id}`, {'id': id}, tok); + const response = await axios.patch(`${process.env.REACT_APP_BACKEND_URL}/recipes/${id}`, {'id': id}, tok); if (response.status === 201) { console.log("FAVORITED RECIPE"); } else { @@ -103,7 +103,7 @@ export const IngredientProvider = ({ children }) => { const unfavorite_recipe = async (id, token) => { const tok = {headers: {'token': token}}; try { - const response = await axios.delete(`https://cookmyfridge-backend.azurewebsites.net/recipes/${id}`, tok); + const response = await axios.delete(`${process.env.REACT_APP_BACKEND_URL}/recipes/${id}`, tok); if (response.status === 201) { console.log("UNFAVORITED RECIPE"); } else { @@ -127,7 +127,7 @@ export const IngredientProvider = ({ children }) => { const get_recipe = async (token) => { try { const tok = {headers: {'token': token}} - const response = await axios.get("https://cookmyfridge-backend.azurewebsites.net/recipes", tok); + const response = await axios.get(`${process.env.REACT_APP_BACKEND_URL}/recipes`, tok); for (let fav of response.data) { fav['favorite'] = true; } @@ -144,7 +144,7 @@ export const IngredientProvider = ({ children }) => { if (check(ingredient.slice(-1)[0]) === false) { const new_ingredient = {'ingredients': ingredient} const tok = {headers: {'token': token}} - const response = await axios.put('https://cookmyfridge-backend.azurewebsites.net/ingredients', new_ingredient, tok); + const response = await axios.put(`${process.env.REACT_APP_BACKEND_URL}/ingredients`, new_ingredient, tok); if (response.status === 201) { setIngredients(ingredient); @@ -153,7 +153,7 @@ export const IngredientProvider = ({ children }) => { } const get_ingredients = async (token) => { - const response = await axios.get('https://cookmyfridge-backend.azurewebsites.net/ingredients', {headers:{'token': token}}); + const response = await axios.get(`${process.env.REACT_APP_BACKEND_URL}/ingredients`, {headers:{'token': token}}); if (response.status === 201) { const new_ingredients = response.data.ingredients_list.ingredients @@ -165,7 +165,7 @@ export const IngredientProvider = ({ children }) => { const delete_ingredient = async (ingredient, token) => { const new_ingredient = {'ingredients': ingredient } const tok = {headers: {'token': token}} - const response = await axios.put(`https://cookmyfridge-backend.azurewebsites.net/ingredients`, new_ingredient, tok); + const response = await axios.put(`${process.env.REACT_APP_BACKEND_URL}/ingredients`, new_ingredient, tok); if (response.status === 201) { setIngredients(ingredient); } From 23bcd6f3c7371390d1e8a15db8d4099486d6cc5e Mon Sep 17 00:00:00 2001 From: Aaron Ahmadyar Date: Thu, 14 Sep 2023 18:25:59 -0700 Subject: [PATCH 14/15] Fixed imports --- backend/middleware.js | 4 ++++ backend/routes/authRoutes.js | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/backend/middleware.js b/backend/middleware.js index 602280c..c43079f 100644 --- a/backend/middleware.js +++ b/backend/middleware.js @@ -1,5 +1,9 @@ const jwt = require("jsonwebtoken"); +//env for JWT token secret +const dotenv = require("dotenv"); +dotenv.config(); + //middleware to authenticate token, used for protected routes async function authenticateToken(req, res, next) { //let token = req.headers.Authorization.split(" ")[1]; diff --git a/backend/routes/authRoutes.js b/backend/routes/authRoutes.js index ac75381..8fccd73 100644 --- a/backend/routes/authRoutes.js +++ b/backend/routes/authRoutes.js @@ -7,6 +7,10 @@ const userServices = require("../controllers/user-services"); //JWT module const jwt = require("jsonwebtoken"); +//env for JWT token secret +const dotenv = require("dotenv"); +dotenv.config(); + function generateAccessToken(id) { /* Generates JWT From 7420819f02bad85b71db368bc3234460bff65f05 Mon Sep 17 00:00:00 2001 From: Aaron Ahmadyar Date: Thu, 14 Sep 2023 18:37:55 -0700 Subject: [PATCH 15/15] reverted some changes --- .../src/components/context/AuthProvider.js | 4 ++-- .../components/context/ingredients_context.js | 20 +++++++++---------- react-frontend/src/pages/login_form.js | 1 - 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/react-frontend/src/components/context/AuthProvider.js b/react-frontend/src/components/context/AuthProvider.js index da7de31..1e62cea 100644 --- a/react-frontend/src/components/context/AuthProvider.js +++ b/react-frontend/src/components/context/AuthProvider.js @@ -15,7 +15,7 @@ export const AuthProvider = ({ children }) => { const navigate = useNavigate(); const handleRegister = async (user) => { - const response = await axios.post(`${process.env.REACT_APP_BACKEND_URL}/register`, user); + const response = await axios.post(`https://cookmyfridge-backend.azurewebsites.net/register`, user); const token = response.data['token'] setToken(token); @@ -47,7 +47,7 @@ export const AuthProvider = ({ children }) => { console.log("In Login"); try{ - const response = await axios.post(`${process.env.REACT_APP_BACKEND_URL}/login`, user); + const response = await axios.post(`https://cookmyfridge-backend.azurewebsites.net/login`, user); if (response.status === 201){ const token = response.data['token']; setToken(token); diff --git a/react-frontend/src/components/context/ingredients_context.js b/react-frontend/src/components/context/ingredients_context.js index 9b98f09..7848f26 100644 --- a/react-frontend/src/components/context/ingredients_context.js +++ b/react-frontend/src/components/context/ingredients_context.js @@ -22,7 +22,7 @@ export const IngredientProvider = ({ children }) => { const get_ratings = async (recipe_id, token) => { try { const tok = {headers: {'token': token}} - const response = await axios.get(`${process.env.REACT_APP_BACKEND_URL}/recipes/${recipe_id}/ratings`, tok); + const response = await axios.get(`https://cookmyfridge-backend.azurewebsites.net/recipes/${recipe_id}/ratings`, tok); setRatings(response.data.ratings); return response.data; @@ -34,7 +34,7 @@ export const IngredientProvider = ({ children }) => { const get_recipeById = async (recipe_id, token) => { try { const tok = {headers: {'token': token}}; - const response = await axios.get(`${process.env.REACT_APP_BACKEND_URL}/${recipe_id}`, tok); + const response = await axios.get(`https://cookmyfridge-backend.azurewebsites.net/recipes/${recipe_id}`, tok); return response.data; } catch (error) { @@ -45,7 +45,7 @@ export const IngredientProvider = ({ children }) => { const send_rating = async (recipe_id, rating, token) => { const tok = {headers: {'token': token}} try { - const response = await axios.patch(`${process.env.REACT_APP_BACKEND_URL}/recipes/${recipe_id}/ratings`, {'rating':rating}, tok); + const response = await axios.patch(`https://cookmyfridge-backend.azurewebsites.net/recipes/${recipe_id}/ratings`, {'rating':rating}, tok); setRatings(response.data['ratings']); } catch (error) { console.log(error); @@ -55,7 +55,7 @@ export const IngredientProvider = ({ children }) => { const send_recipe = async (recipe, token) => { const tok = {headers: {'token': token}}; try { - const response = await axios.post(`${process.env.REACT_APP_BACKEND_URL}/recipes`, recipe, tok); + const response = await axios.post("https://cookmyfridge-backend.azurewebsites.net/recipes", recipe, tok); const r = response.data['recipes_list']; let favorites = [] if (response.data['favorites'] === undefined) { @@ -89,7 +89,7 @@ export const IngredientProvider = ({ children }) => { const favorite_recipe = async (id, token) => { const tok = {headers: {'token': token}}; try { - const response = await axios.patch(`${process.env.REACT_APP_BACKEND_URL}/recipes/${id}`, {'id': id}, tok); + const response = await axios.patch(`https://cookmyfridge-backend.azurewebsites.net/recipes/${id}`, {'id': id}, tok); if (response.status === 201) { console.log("FAVORITED RECIPE"); } else { @@ -103,7 +103,7 @@ export const IngredientProvider = ({ children }) => { const unfavorite_recipe = async (id, token) => { const tok = {headers: {'token': token}}; try { - const response = await axios.delete(`${process.env.REACT_APP_BACKEND_URL}/recipes/${id}`, tok); + const response = await axios.delete(`https://cookmyfridge-backend.azurewebsites.net/recipes/${id}`, tok); if (response.status === 201) { console.log("UNFAVORITED RECIPE"); } else { @@ -127,7 +127,7 @@ export const IngredientProvider = ({ children }) => { const get_recipe = async (token) => { try { const tok = {headers: {'token': token}} - const response = await axios.get(`${process.env.REACT_APP_BACKEND_URL}/recipes`, tok); + const response = await axios.get("https://cookmyfridge-backend.azurewebsites.net/recipes", tok); for (let fav of response.data) { fav['favorite'] = true; } @@ -144,7 +144,7 @@ export const IngredientProvider = ({ children }) => { if (check(ingredient.slice(-1)[0]) === false) { const new_ingredient = {'ingredients': ingredient} const tok = {headers: {'token': token}} - const response = await axios.put(`${process.env.REACT_APP_BACKEND_URL}/ingredients`, new_ingredient, tok); + const response = await axios.put('https://cookmyfridge-backend.azurewebsites.net/ingredients', new_ingredient, tok); if (response.status === 201) { setIngredients(ingredient); @@ -153,7 +153,7 @@ export const IngredientProvider = ({ children }) => { } const get_ingredients = async (token) => { - const response = await axios.get(`${process.env.REACT_APP_BACKEND_URL}/ingredients`, {headers:{'token': token}}); + const response = await axios.get('https://cookmyfridge-backend.azurewebsites.net/ingredients', {headers:{'token': token}}); if (response.status === 201) { const new_ingredients = response.data.ingredients_list.ingredients @@ -165,7 +165,7 @@ export const IngredientProvider = ({ children }) => { const delete_ingredient = async (ingredient, token) => { const new_ingredient = {'ingredients': ingredient } const tok = {headers: {'token': token}} - const response = await axios.put(`${process.env.REACT_APP_BACKEND_URL}/ingredients`, new_ingredient, tok); + const response = await axios.put(`https://cookmyfridge-backend.azurewebsites.net/ingredients`, new_ingredient, tok); if (response.status === 201) { setIngredients(ingredient); } diff --git a/react-frontend/src/pages/login_form.js b/react-frontend/src/pages/login_form.js index 6964811..9bc4be2 100644 --- a/react-frontend/src/pages/login_form.js +++ b/react-frontend/src/pages/login_form.js @@ -121,7 +121,6 @@ function LoginForm() { async function onSubmit(e) { e.preventDefault(); try { - console.log("USER", user); const c = await Auth.onLogin(user) if (c) { setBad("BAD PASSWORD");