218 lines
5.6 KiB
JavaScript
218 lines
5.6 KiB
JavaScript
|
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
|
||
|
};
|