remove restaurant / changed add user

This commit is contained in:
2020-09-16 09:30:31 +02:00
parent cec24fa01a
commit a5232e7257
6 changed files with 121 additions and 20 deletions

View File

@@ -73,6 +73,10 @@
- ##### **password**: _String_ (required) - ##### **password**: _String_ (required)
- ##### **firstname**: _String_ (required) - ##### **firstname**: _String_ (required)
- ##### **lastname**: _String_ (required) - ##### **lastname**: _String_ (required)
- ##### **billing**
- ##### **NIP**: _String_
- ##### **adress**: _String_
- ##### **companyName**: _String_
- ##### **restaurants**: [*mongoose.Types.ObjectId*] - ##### **restaurants**: [*mongoose.Types.ObjectId*]
- ##### **trialUsed**: _Boolean_ - ##### **trialUsed**: _Boolean_
<br> <br>
@@ -111,6 +115,14 @@
<br> <br>
- ### **/restaurant/delete**
- #### **POST**
Takes a **restaurantId** parameter and a **JWT token(header)**, and tries to remove the restaurant from the database and from user. If successfull returns **200**, if failed returns error with a code.
<br>
* ### **/img** * ### **/img**
- #### **POST** - #### **POST**
@@ -135,6 +147,22 @@
<br> <br>
* ### **/user/forgotpassword**
- #### **POST**
Takes **email** parameter and if it exists, generates and sends an pass reset link via the email to the owner of the account.
<br>
* ### **/user/resetpass**
- #### **POST**
Takes **token, email, newPass** parameters and if everything checks out, changes user password to the supplied **newPass**.
<br>
- ### **/search** - ### **/search**
- #### **GET** - #### **GET**

View File

@@ -18,6 +18,20 @@ const userSchema = mongoose.Schema({
type: String, type: String,
required: true, required: true,
}, },
billing: {
NIP: {
type: String,
required: true,
},
adress: {
type: String,
required: true,
},
companyName: {
type: String,
required: true,
},
},
restaurants: [mongoose.Types.ObjectId], restaurants: [mongoose.Types.ObjectId],
trialUsed: Boolean, trialUsed: Boolean,
}); });

View File

@@ -4,12 +4,14 @@ import {
addRestaurantToUser, addRestaurantToUser,
fetchRestaurant, fetchRestaurant,
fetchAllDishesForRestaurant, fetchAllDishesForRestaurant,
removeRestaurant,
} from "../services/databaseServices.js"; } from "../services/databaseServices.js";
import { import {
decodeAndSanitize, decodeAndSanitize,
validateRestaurant, validateRestaurant,
handleError, handleError,
validateUserToken, validateUserToken,
verifyRestaurantAccess,
} from "../services/services.js"; } from "../services/services.js";
import Restaurant from "../models/restaurant.js"; import Restaurant from "../models/restaurant.js";
@@ -63,8 +65,8 @@ router.post("/delete", async (req, res) => {
const token = req.headers["x-auth-token"]; const token = req.headers["x-auth-token"];
const user = validateUserToken(token); const user = validateUserToken(token);
await validateRestaurant(req.body.restaurantId); await validateRestaurant(req.body.restaurantId);
//check access await verifyRestaurantAccess(req.body.restaurantId, user);
//delete restaurant await removeRestaurant(req.body.restaurantId, user.id);
res.send("Restauracja została pomyślnie usunięta."); res.send("Restauracja została pomyślnie usunięta.");
} catch (error) { } catch (error) {
handleError(error, res); handleError(error, res);

View File

@@ -31,6 +31,21 @@ export function composeNewContact(request) {
name: "UserID", name: "UserID",
value: request._id, value: request._id,
}, },
{
type: "CUSTOM",
name: "NIP",
value: request.NIP,
},
{
type: "CUSTOM",
name: "CompanyName",
value: request.companyName,
},
{
type: "CUSTOM",
name: "CompanyAdress",
value: request.adress,
},
], ],
}; };
return contact; return contact;
@@ -44,6 +59,11 @@ export async function createUser(request) {
password: password, password: password,
firstname: request.body.firstname, firstname: request.body.firstname,
lastname: request.body.lastname, lastname: request.body.lastname,
billing: {
NIP: request.body.NIP,
adress: request.body.adress,
companyName: request.body.companyName,
},
}); });
return user; return user;
} }

View File

@@ -5,18 +5,34 @@ import { newError } from "./services.js";
export async function changeUserPass(userId, newPass) { export async function changeUserPass(userId, newPass) {
User.findByIdAndUpdate(userId, { $set: { password: newPass } }).catch((e) => { User.findByIdAndUpdate(userId, { $set: { password: newPass } }).catch((e) => {
throw newError("Cannot change password", 500); throw newError("Zmiana hasła nie powiodła się.", 500);
}); });
} }
export async function removeDish(dishId) { export async function removeDish(dishId) {
const deletedDoc = await Dish.findByIdAndDelete(dishId).catch((e) => { const deletedDoc = await Dish.findByIdAndDelete(dishId).catch((e) => {
throw newError("Unable to delete Dish", 500); throw newError("Usunięcie dania nie powiodło się.", 500);
}); });
await Restaurant.findByIdAndUpdate(deletedDoc.restaurantId, { await Restaurant.findByIdAndUpdate(deletedDoc.restaurantId, {
$pull: { dishes: dishId }, $pull: { dishes: dishId },
}).catch((error) => { }).catch((error) => {
throw newError("Unable to remove Dish from restaurant", 500); throw newError("Usunięcie dania z restauracji nie powiodło się.", 500);
});
}
export async function removeRestaurant(restaurantId, userId) {
const deletedDoc = await Restaurant.findByIdAndDelete(restaurantId).catch(
(e) => {
throw newError("Usunięcie nie powiodło się.", 500);
}
);
await User.findByIdAndUpdate(userId, {
$pull: { restaurants: restaurantId },
}).catch((e) => {
throw newError(
"Usunięcie restauracji z użytkownika nie powiodło się.",
500
);
}); });
} }

View File

@@ -27,20 +27,21 @@ export function handleError(error, responseObject) {
} }
export async function validateRestaurant(id) { export async function validateRestaurant(id) {
if (!mongoose.Types.ObjectId.isValid(id)) throw newError("Invalid ID", 204); if (!mongoose.Types.ObjectId.isValid(id))
throw newError("Nieprawidłowy ID", 204);
let valid = await Restaurant.exists({ _id: id }); let valid = await Restaurant.exists({ _id: id });
if (valid !== true) throw newError("Restaurant doesn't exist", 404); if (valid !== true) throw newError("Restauracja nie istnieje w bazie.", 404);
return true; return true;
} }
export function decodeAndSanitize(query) { export function decodeAndSanitize(query) {
if (!query) throw newError("Nothing to sanitize...", 204); if (!query) throw newError("Brak danych.", 204);
return sanitizer.sanitize.keepUnicode(decodeURI(query)); return sanitizer.sanitize.keepUnicode(decodeURI(query));
} }
export async function checkPassword(password, hash) { export async function checkPassword(password, hash) {
const result = await bcrypt.compare(password, hash); const result = await bcrypt.compare(password, hash);
if (!result) throw newError("Wrong password :(", 401); if (!result) throw newError("Hasło nieprawidłowe", 401);
} }
export function generateAuthToken(user) { export function generateAuthToken(user) {
@@ -49,6 +50,7 @@ export function generateAuthToken(user) {
email: user.email, email: user.email,
firstname: user.firstname, firstname: user.firstname,
lastname: user.lastname, lastname: user.lastname,
billing: user.billing,
id: user.id, id: user.id,
restaurants: user.restaurants, restaurants: user.restaurants,
}, },
@@ -76,39 +78,58 @@ export function generatePasswordResetLink(email) {
} }
export async function checkEmailTaken(email) { export async function checkEmailTaken(email) {
if (!email) throw newError("No input email", 204); if (!email) throw newError("Brak adresu email", 204);
await User.exists({ email: email }).then((res) => { await User.exists({ email: email }).then((res) => {
if (res) { if (res) {
throw newError("Email is taken", 409); throw newError("Adres email zajęty", 409);
} }
}); });
} }
export function validateUserToken(token) { export function validateUserToken(token) {
if (!token) throw newError("Invalid user token", 401); if (!token) throw newError("Brak dostępu", 401);
const verified = jwt.verify(token, jwtSecret, { ignoreExpiration: false }); const verified = jwt
if (!verified) throw newError("Invalid user token", 401); .verify(token, jwtSecret, { ignoreExpiration: false })
.catch((e) => {
throw newError("Brak dostępu", 401);
});
if (!verified) throw newError("Brak dostępu", 401);
return verified; return verified;
} }
export async function validateDishId(id) { export async function validateDishId(id) {
if (!mongoose.Types.ObjectId.isValid(id)) { if (!mongoose.Types.ObjectId.isValid(id)) {
throw newError("Invalid ID", 400); throw newError("Niewłaściwy ID", 400);
} }
const dishDoesExist = Dish.exists({ _id: id }); const dishDoesExist = Dish.exists({ _id: id });
if (!dishDoesExist) throw newError("Dish doesn't exist", 404); if (!dishDoesExist) throw newError("Te danie nie istnieje w bazie.", 404);
} }
export async function verifyDishAccess(dishId, decodedToken) { export async function verifyDishAccess(dishId, decodedToken) {
const fetch = await User.findById(decodedToken.id, "restaurants"); const fetch = await User.findById(decodedToken.id, "restaurants").catch(
(error) => {
throw newError("Nie znaleziono użytkownika.", 500);
}
);
const restaurants = fetch.restaurants; const restaurants = fetch.restaurants;
const restaurantId = await Dish.findById(dishId, "restaurantId").catch( const restaurantId = await Dish.findById(dishId, "restaurantId").catch(
(error) => { (error) => {
throw newError("Couldn't fetch Dish", 404); throw newError("Nie znaleziono dania.", 404);
} }
); );
const valid = restaurants.includes(restaurantId.restaurantId); const valid = restaurants.includes(restaurantId.restaurantId);
if (!valid) throw newError("You don't have access to this Dish.", 401); if (!valid) throw newError("Nie masz dostępu do tego dania.", 401);
}
export async function verifyRestaurantAccess(restaurantId, decodedToken) {
const fetch = await User.findById(decodedToken.id, "restaurants").catch(
(error) => {
throw newError("Nie znaleziono użytkownika.", 500);
}
);
const restaurants = fetch.restaurants;
const valid = restaurants.includes(restaurantId);
if (!valid) throw newError("Nie masz dostępu do tej restauracji.", 401);
} }
export function yearFromNowDate() { export function yearFromNowDate() {
@@ -141,7 +162,7 @@ export async function hashPass(pass) {
const hash = await bcrypt.hash(pass, salt); const hash = await bcrypt.hash(pass, salt);
return hash; return hash;
} catch (error) { } catch (error) {
throw newError("Internal error", 500); throw newError("Błąd", 500);
} }
} }