Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Code/database/user-auth/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import express from "express"
import cors from "cors"
import { dbConnect } from "./db.js"
import tokenValidation from "./middlewares/tokenValidation.js"

const app = express()
const PORT = 4000

app.use(express.json())
app.use(cors())

import router from "./controller/user.js"
import recipeRouter from "./controller/recipe.js"
app.use("/", router)
app.use("/recipe", tokenValidation, recipeRouter)

app.listen(PORT, () => {
dbConnect()
console.log(`[server]: listening on port ${PORT}`)
})
82 changes: 82 additions & 0 deletions Code/database/user-auth/controller/recipe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import express from "express";
const router = express.Router()
import { mongoose } from "../db.js";
import jwt from "jsonwebtoken"
import tokenValidation from "../middlewares/tokenValidation.js"

import Recipe from "../models/Recipe.js";

const JWT_KEY = "Shh it's a secret"



//Get all recipes
router.get("/", tokenValidation, async (req, res) => {
try{
const recipe = await Recipe.find()
res.send(recipe)
} catch(err) {
res.status(500).send({message: err.message})
}
})

// Get a single recipe by id
router.get("/find/:id", tokenValidation, async (req, res) => {
if (mongoose.Types.ObjectId.isValid(req.params.id)) {
const recipe= await Recipe.findOne({ _id: req.params.id })
recipe ? res.json(recipe) : res.status(404).send("Recipe not found")
} else {
res.status(404).send("Invalid recipe id")
}
})

//Create a new recipe
router.post("/", tokenValidation, async (req, res) => {
try {
const newRecipe = new Recipe({...req.body, createdBy: req.user._id})
await newRecipe.save()
res.send(`Added ${req.body.title} recipe`)
} catch (err) {
res.status(400).send(err)
}
})

//Update an existing recipe
router.put("/update/:id", tokenValidation, async (req, res) => {
try {
const recipe = await Recipe.findById(req.params.id);
if (!recipe) {
return res.status(404).send("Recipe not found");
}
if (recipe.createdBy.toString() !== req.user._id.toString()) {
return res.status(403).send("You do not have permission to update this recipe");
}
Object.assign(recipe, req.body);
await recipe.save();
res.send(`Updated ${recipe.title} recipe`);
} catch (err) {
console.log("Error in update recipe:", err);
res.status(400).send(err);
}
})

//Delete a recipe
router.delete("/delete/:id", tokenValidation, async (req, res) => {
try {
const recipe = await Recipe.findById(req.params.id);
if (!recipe) {
return res.status(404).send("Recipe not found");
}
if (recipe.createdBy.toString() !== req.user._id.toString()) {
return res.status(403).send("You do not have permission to delete this recipe");
}
await recipe.deleteOne();
res.send(`Deleted ${recipe.title} recipe`);
} catch (err) {
console.log("Error in delete recipe:", err);
res.status(400).send(err);
}
})

export default router

49 changes: 49 additions & 0 deletions Code/database/user-auth/controller/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import express from "express";
const router = express.Router()
import bcrypt from "bcrypt"
import jwt from "jsonwebtoken"
import { mongoose } from "../db.js";

import User from "../models/User.js";

const JWT_KEY = "Shh it's a secret"
const SALT = 20


const generateAuthToken = (user) => {
const token = jwt.sign({ _id: user._id.toString() }, JWT_KEY, { expiresIn: "1h" });
return token;
};

router.post("/register", async (req, res) => {
try {
const {email, password} = req.body
const newUser = new User({
email,
password: bcrypt.hashSync(password, SALT)
})
await newUser.save()
res.send("User registered")
} catch(err){
console.log(err)
res.send(err)
}
})

router.post("/login", async (req, res)=>{
try{
const {email,password} = req.body
const user = await User.findOne({email})
if(user && bcrypt.compare(password, user.password)){
const token = jwt.sign({userId: user._id}, JWT_KEY, {expiresIn: "24h"})
res.json({ message: "User Verified", token, user})
} else {
res.send("Invalid login credentials")
}
} catch(err){
console.log(err)
res.status(500).send(err)
}
})

export default router
12 changes: 12 additions & 0 deletions Code/database/user-auth/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import mongoose from "mongoose"

const dbConnect = async () => {
try {
await mongoose.connect("mongodb://localhost:27017/Recipe")
console.log(`[database]: connected to db`)
} catch (err) {
console.warn(`[database error]: ${err}`)
}
}

export { dbConnect, mongoose }
40 changes: 40 additions & 0 deletions Code/database/user-auth/middlewares/tokenValidation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import jwt from "jsonwebtoken";
import User from "../models/User.js";

const JWT_KEY = "Shh it's a secret";

const tokenValidation = async (req, res, next) => {
try {
const authHeader = req.headers['authorization'];

if (!authHeader) {
console.error("Authorization header is missing");
return res.status(401).send({ error: "Please authenticate." });
}

if (!authHeader.startsWith("Bearer ")) {
console.error("Authorization header is malformed:", authHeader);
return res.status(401).send({ error: "Please authenticate." });
}

const token = authHeader.replace("Bearer ", "");
console.log("Token:", token);

const decoded = jwt.verify(token, JWT_KEY);
console.log("Decoded token:", decoded);

const user = await User.findById(decoded.userId);
if (!user) {
console.error("User not found for token:", decoded);
return res.status(401).send({ error: "Please authenticate." });
}

req.user = user;
next();
} catch (err) {
console.error("Error in token validation:", err);
res.status(401).send({ error: "Please authenticate." });
}
};

export default tokenValidation;
29 changes: 29 additions & 0 deletions Code/database/user-auth/models/Recipe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { mongoose } from "../db.js";

const Recipe = new mongoose.Schema({
title: {
type: String,
maxlength: 100
},
author: {
type: String,
maxlength: 50
},
ingredients: [String],

instructions: {
type: String,
maxlength: 2000
},

createdBy: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
}

})



export default mongoose.model("Recipe", Recipe)

16 changes: 16 additions & 0 deletions Code/database/user-auth/models/User.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { mongoose } from "../db.js";
import bycrpt from "bcrypt"

const User = new mongoose.Schema({
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
}
})

export default mongoose.model("User", User)
Loading