Skip to content

Commit

Permalink
Merge pull request #88 from aahmadyar123/express-router
Browse files Browse the repository at this point in the history
Express router
  • Loading branch information
aahmadyar123 authored Sep 15, 2023
2 parents c349850 + 7420819 commit b4a3054
Show file tree
Hide file tree
Showing 9 changed files with 442 additions and 374 deletions.
392 changes: 23 additions & 369 deletions backend/backend.js

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions backend/middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
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];
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,
};
21 changes: 21 additions & 0 deletions backend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
76 changes: 76 additions & 0 deletions backend/routes/authRoutes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
const express = require("express");
const router = express.Router();

//DB models
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
:param id: user DB ._id
:return: JWT token
*/
return jwt.sign(id, process.env.TOKEN_SECRET, { expiresIn: "1h" });
}

// --------------------------------------------------
// 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);
console.log(result);

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;
console.log(user);
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.");
}
});

router.get("/login", async (req, res) => {
res.send("<h1>test<h1>");
});

module.exports = router;
51 changes: 51 additions & 0 deletions backend/routes/ingredientRoutes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
const express = require("express");
const router = express.Router();


//DB models
const userServices = require("../controllers/user-services");

// --------------------------------------------------
// 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.");
}
});


module.exports = router;
152 changes: 152 additions & 0 deletions backend/routes/recipeRoutes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
const express = require("express");
const router = express.Router();

// Spoonacular API methods
const recipeAPI = require("../recipeAPI.js");

//DB models
const userServices = require("../controllers/user-services");
const recipeServices = require("../controllers/recipe-services");

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);
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);
}
});

module.exports = router;
Loading

0 comments on commit b4a3054

Please sign in to comment.