From b2a853e183616323558d46b2fbdf5380dd58abc0 Mon Sep 17 00:00:00 2001 From: NewPerson Date: Sat, 25 May 2024 00:10:46 +0300 Subject: [PATCH] back add --- server/routers/edateam/auth.js | 36 +++++ server/routers/edateam/controllers.js | 217 ++++++++++++++++++++++++++ server/routers/edateam/index.js | 24 ++- server/routers/edateam/key.js | 3 + server/routers/edateam/main.js | 51 ++++++ server/routers/edateam/user.js | 35 +++++ 6 files changed, 359 insertions(+), 7 deletions(-) create mode 100644 server/routers/edateam/auth.js create mode 100644 server/routers/edateam/controllers.js create mode 100644 server/routers/edateam/key.js create mode 100644 server/routers/edateam/main.js create mode 100644 server/routers/edateam/user.js diff --git a/server/routers/edateam/auth.js b/server/routers/edateam/auth.js new file mode 100644 index 0000000..551cc20 --- /dev/null +++ b/server/routers/edateam/auth.js @@ -0,0 +1,36 @@ +const router = require('express').Router(); +const checkPassword = require('pbkdf2-password')(); +const jwt = require('jsonwebtoken'); +const {EDATEAM_JWT_TOKEN} = require('./key'); + +const {getUser, _idToId, getResponse, requiredFields, signUp} = require('./controllers'); + +router.post('/sign-in', requiredFields(['email','password']), async (req, res)=>{ + try{ + const user = await getUser(req.body); + + checkPassword({password:req.body.password, salt:user.salt},async(err, pass, salt, hash )=>{ + if(err){ + throw new Error(err); + } + + if(user.password === hash){ + const {password, salt:_salt, ...rest} = user; + const token = jwt.sign(_idToId(rest), EDATEAM_JWT_TOKEN); + return res.send(getResponse(null, token)); + } + return res.status(400).send(getResponse('Wrong email or password!')); + } ) + } + catch(error){ + res.status(400).send(getResponse(error.message)); + } +}); + +router.post('/sign-up', requiredFields(['email', 'login', 'password']), async (req, res) => { + let error = null + const data = await signUp(req.body).catch((e) => error = e.message) + return res.status(error ? 400 : 200).send(getResponse(error, data)) +}) + +module.exports = router; \ No newline at end of file diff --git a/server/routers/edateam/controllers.js b/server/routers/edateam/controllers.js new file mode 100644 index 0000000..f600a5c --- /dev/null +++ b/server/routers/edateam/controllers.js @@ -0,0 +1,217 @@ +const ObjectId = require('mongodb').ObjectId; +const getHash = require('pbkdf2-password')(); +const { getDB } = require('../../utils/mongo'); + +const USERS_COLLECTION = 'users'; +const RECIPES_COLLECTION = 'recipes_collection'; +const FAVORITES_USER = 'favorites_user' +let db =null; + +const connect = async () => { + db = await getDB('edateam'); +}; + +const init = async () => { + await connect(); +}; + +init(); + +const _idToId = (data) => { + const { _id, ...rest } = data; + return { + id: _id, + ...rest + }; +} + +const _idToArray = (data) => { + const _idToMap = data.map((item) => _idToId(item)); + return _idToMap; +} + +const getResponse = (error, data, success = true) => { + if (error) { + return { + success: false, + error, + } + } + + return { + success, + data, + } +} + +const signUp = async ({ email, login, password }) => { + try { + db = await getDB('edateam'); + const userCollection = db.collection(USERS_COLLECTION); + + const userData = await userCollection.findOne({ + $or: [ + { login }, + { email } + ] + }) + + if (userData?.login === login) { + throw new Error('This login already in db!\nPlease come up with another login!'); + } + + if (userData?.email === email) { + throw new Error('This email already in db!\nPlease come up with another email!'); + } + + return new Promise((resolve, reject) => { + getHash({ password }, async (err, pass, salt, hash) => { + if (err) { + return reject(err); + } + const insertedCount = await userCollection.insertOne({ email, login, password: hash, salt }); + + if (!insertedCount) { + return reject(new Error('Insert error!')); + } + resolve({}); + }); + }); + + } catch (error) { + console.error(error); + throw error; + } +}; + +const getUser = async ({ email }) => { + if (db === null) { + throw new Error('no db connection :(('); + } + + try { + const userCollection = db.collection(USERS_COLLECTION); + const userData = await userCollection.findOne({ email }); + if (userData) { + return userData; + } + throw new Error('Wrong email or password!'); + } catch (error) { + throw new Error(error); + } +} + +const getListRecipes = async () => { + try { + db = await getDB('edateam'); + const recipesCollection = db.collection(RECIPES_COLLECTION); + const recipesData = await recipesCollection.find().toArray(); + + if (recipesData.length > 0) { + return _idToArray(recipesData); + } else { + throw new Error('No recipes found in the database!'); + } + } catch (error) { + console.error('Error in getListRecipes:', error.message); + throw new Error(error.message); + } +}; + +const getRecipe = async (dishId ) => { + try { + db = await getDB('edateam'); + const recipesCollection = db.collection(RECIPES_COLLECTION); + const id = dishId.id; + const recipeData = await recipesCollection.findOne({ _id :new ObjectId(id) } ); + if (recipeData!=null) { + return _idToId(recipeData); + } + + throw new Error('Not found recipe'); + } catch (error) { + throw new Error(error); + } +} + +const addRecipe = async (recipe) => { + try { + db = await getDB('edateam'); + const recipesCollection = db.collection(RECIPES_COLLECTION); + const result = await recipesCollection.insertOne(recipe); + + if (!result.insertedId) { + throw new Error('Recipe insertion failed'); + } + + return { + success: true, + id: result.insertedId + }; + } catch (error) { + console.error('Error in addRecipe:', error.message); + throw new Error(error.message); + } +}; + + +const requiredFields = (fields) => (req, res, next) => { + // eslint-disable-next-line no-restricted-syntax + for (const fieldName of fields) { + if (!req.body[fieldName]) { + throw new Error(`Параметр ${fieldName} не установлен`) + } + } + + next() +} + +const addFavorite = async (userId, recipeId) => { + + try { + db = await getDB('edateam'); + const favoritesCollection = db.collection(FAVORITES_USER); + const result = await favoritesCollection.updateOne( + { userId: new ObjectId(userId) }, + { $addToSet: { favorites: new ObjectId(recipeId) } }, + { upsert: true } + ); + return result; + } catch (error) { + throw new Error('Error adding favorite: ' + error.message); + } +}; + +const getFavorites = async (userId) => { + try { + db = await getDB('edateam'); + const favoritesCollection = db.collection(FAVORITES_USER); + const userFavorites = await favoritesCollection.findOne({ userId: new ObjectId(userId) }); + + if (!userFavorites || !userFavorites.favorites || userFavorites.favorites.length === 0) { + return []; + } + + const recipesCollection = db.collection(RECIPES_COLLECTION); + const favoriteRecipes = await recipesCollection.find({ _id: { $in: userFavorites.favorites } }).toArray(); + + return favoriteRecipes; + } catch (error) { + console.error(error); + throw new Error("Failed to get user favorites with recipes"); + } +}; + +module.exports = { + getUser, + signUp, + getResponse, + _idToId, + _idToArray, + getListRecipes, + getRecipe, + addRecipe, + requiredFields, + getFavorites, + addFavorite +}; diff --git a/server/routers/edateam/index.js b/server/routers/edateam/index.js index eae4920..e300083 100644 --- a/server/routers/edateam/index.js +++ b/server/routers/edateam/index.js @@ -1,15 +1,25 @@ const router = require('express').Router(); router.get('/recipe-data', (request, response) => { - response.send(require('./json/recipe-data/success.json')); - }); - -router.get('/userpage-data', (req, res)=>{ - res.send(require('./json/userpage-data/success.json')); + response.send(require('../json/recipe-data/success.json')); }); -router.get('/homepage-data', (req, res)=>{ - res.send(require('./json/homepage-data/success.json')); +router.get('/userpage-data', (req, res) => { + res.send(require('../json/userpage-data/success.json')); }); +router.post('/userpage-data', (req, res) => { + res.send(require('../json/userpage-data/success.json')); +}); + +router.get('/homepage-data', (req, res) => { + res.send(require('../json/homepage-data/success.json')); +}); + +router.use('/auth', require('./auth')); + +router.use('/recipe', require('./user')); + +router.use('/main', require('./main')); + module.exports = router; diff --git a/server/routers/edateam/key.js b/server/routers/edateam/key.js new file mode 100644 index 0000000..8c8a349 --- /dev/null +++ b/server/routers/edateam/key.js @@ -0,0 +1,3 @@ +const EDATEAM_JWT_TOKEN = 'secretyk token'; + +module.exports = {EDATEAM_JWT_TOKEN}; \ No newline at end of file diff --git a/server/routers/edateam/main.js b/server/routers/edateam/main.js new file mode 100644 index 0000000..1f30494 --- /dev/null +++ b/server/routers/edateam/main.js @@ -0,0 +1,51 @@ +const { getListRecipes , getRecipe, addFavorite , getFavorites} = require('./controllers'); + +const router = require('express').Router(); + +router.get('/recipes', async (req, res) => { + try { + const result = await getListRecipes(); + return res.status(200).json({ success: true, data: result }); + } catch (error) { + console.error('Error in GET /recipes:', error.message); + return res.status(500).json({ success: false, message: error.message }); + } +}); + +router.post('/recipe', async(req,res)=>{ + try{ + const result = await getRecipe(req.body); + + return res.status(200).json({success:true, data: result}); + } + catch(error){ + console.error('Error in GET /recipes:', error.message); + return res.status(500).json({ success: false, message: error.message }); + } +}) + +router.post('/favorites', async (req, res) => { + try { + + const { userId, recipeId } = req.body; + const result = await addFavorite(userId, recipeId); + return res.status(200).json({ success: true, data: result }); + } catch (error) { + console.error('Error in POST /favorites:', error.message); + return res.status(500).json({ success: false, message: error.message }); + } +}); + +router.post('/get-favorites', async(req,res) =>{ + try { + const { userId } = req.body; + const result = await getFavorites(userId); + console.log(result) + return res.status(200).json({ success: true, data: result }); + } catch (error) { + console.error('Error in POST /get-favorites:', error.message); + return res.status(500).json({ success: false, message: error.message }); + } +}); + +module.exports = router; \ No newline at end of file diff --git a/server/routers/edateam/user.js b/server/routers/edateam/user.js new file mode 100644 index 0000000..5e1bd39 --- /dev/null +++ b/server/routers/edateam/user.js @@ -0,0 +1,35 @@ +const { requiredFields , getFavorites, addRecipe} = require('./controllers'); + +const router = require('express').Router(); + +router.post('/favorites', requiredFields('id'), async(req,res)=>{ + try{ + const recipes = await getFavorites(req.body); + res.status(200).send(getResponse(recipes)); + } + catch(error){ + res.status(400).send(getResponse(error.message)); + } +}) + +router.post('/add-recept', async (req, res) => { + let error = null; + let result = null; + + try { + result = await addRecipe(req.body); + } catch (e) { + error = e.message; + } + + if (error) { + console.error(`Error in POST /add-recept: ${error}`); + } + + return res.status(error ? 500 : 201).json({ + message: error ? error : 'Recipe added successfully', + id: result?.id + }); +}); + +module.exports = router; \ No newline at end of file -- 2.45.2