customer-dashboard-api/src/controllers/usersController.ts

374 lines
8.7 KiB
TypeScript

import { Request, Response } from "express";
import logger from "../logger/logger";
import {
isAccountNameValid,
isPasswordValid,
isUserIdValid,
isUsernameValid,
} from "../validator/validator";
import {
decodeBase64,
getUserSession,
hashPassword,
newUserId,
} from "../utils/utils";
import User from "../models/user";
import { Roles } from "../utils/constants";
import Store from "../models/store";
export async function AddEmployee(req: Request, res: Response) {
try {
let {
storeId,
username,
accountName,
password,
calendarMaxFutureBookingDays,
calendarMinEarliestBookingTime,
} = req.body;
// validate request
if (!storeId || !username || !accountName || !password) {
return res.status(400).send({ err: "invalid request" });
}
// verify if requester is a store master
const requesterSession = await getUserSession(req);
if (!requesterSession) {
logger.debug("Requester session not found");
return res.status(401).send({ err: "unauthorized" });
}
const store = await Store.findOne({
where: {
store_id: storeId,
},
});
if (!store) {
logger.debug("Store not found");
return res.status(400).send({ err: "invalid request" });
}
if (store.owner_user_id !== requesterSession.user_id) {
logger.debug("Requester is not the store owner");
return res.status(401).send({ err: "unauthorized" });
}
// validate username and account name
accountName = accountName.toLowerCase();
if (
!isUsernameValid(username) ||
!(await isAccountNameValid(accountName))
) {
return res.status(400).send({ err: "invalid request" });
}
// check if user already exists
const existingUser = await User.findOne({
where: {
account_name: accountName,
},
});
if (existingUser) {
logger.debug(
"User already exists with this accountName: %s",
accountName
);
return res.status(400).send({ err: "invalid request" });
}
// decode password
const decodedPassword = decodeBase64(password);
if (!isPasswordValid(decodedPassword)) {
logger.debug("Password is not valid");
return res.status(400).send({ err: "invalid request" });
}
// hash password
const hashedPassword = await hashPassword(decodedPassword);
// create user
const userId = newUserId();
await User.create({
user_id: userId,
store_id: storeId,
role: Roles.Worker,
account_name: accountName,
username: username,
password: hashedPassword,
calendar_max_future_booking_days: calendarMaxFutureBookingDays,
calendar_min_earliest_booking_time: calendarMinEarliestBookingTime,
})
.then(() => res.status(200).send({ msg: "success" }))
.catch((err) => {
logger.error(err);
res.status(500).send({ err: "invalid request" });
});
} catch (error) {
logger.error(error);
res.status(500).send({ err: "invalid request" });
}
}
export async function GetEmployees(req: Request, res: Response) {
try {
let { storeId } = req.params;
const requesterSession = await getUserSession(req);
if (!requesterSession) {
logger.debug("Requester session not found");
return res.status(401).send({ err: "unauthorized" });
}
// verify if requester is a store master
const store = await Store.findOne({
where: {
store_id: storeId,
},
attributes: [
"owner_user_id",
"calendar_max_future_booking_days",
"calendar_min_earliest_booking_time",
],
});
if (!store) {
logger.debug("Store not found");
return res.status(400).send({ err: "invalid request" });
}
if (store.owner_user_id !== requesterSession.user_id) {
logger.debug("Requester is not the store owner");
return res.status(401).send({ err: "unauthorized" });
}
// find all employees of the requester and select only the username and account name
const employees = await User.findAll({
where: {
store_id: storeId,
},
attributes: [
"user_id",
"username",
"account_name",
"calendar_max_future_booking_days",
"calendar_min_earliest_booking_time",
],
});
// filter out the requester from the employees
const filteredEmployees = employees.filter(
(employee) => employee.user_id !== requesterSession.user_id
);
res.status(200).send({
storeSettings: {
calendar_max_future_booking_days:
store.calendar_max_future_booking_days,
calendar_min_earliest_booking_time:
store.calendar_min_earliest_booking_time,
},
employees: filteredEmployees,
});
} catch (error) {
logger.error(error);
res.status(500).send({ err: "invalid request" });
}
}
export async function UpdateEmployee(req: Request, res: Response) {
try {
let {
userId,
username,
accountName,
calendarMaxFutureBookingDays,
calendarMinEarliestBookingTime,
} = req.body;
// validate username and account name
if (!isUserIdValid(userId)) {
return res.status(400).send({ err: "invalid request" });
}
// verify if requester is a store master
const requesterSession = await getUserSession(req);
if (!requesterSession) {
logger.debug("Requester session not found");
return res.status(401).send({ err: "unauthorized" });
}
const store = await Store.findOne({
where: {
owner_user_id: requesterSession.user_id,
},
});
if (!store) {
logger.debug("Store not found");
return res.status(400).send({ err: "invalid request" });
}
// check if user exists
const existingUser = await User.findOne({
where: {
user_id: userId,
},
});
if (!existingUser) {
logger.debug("User not found");
return res.status(400).send({ err: "invalid request" });
}
// update data
let update = {};
if (accountName) {
accountName = accountName.toLowerCase();
if (!(await isAccountNameValid(accountName))) {
res.status(400).send({ err: "invalid request" });
return;
}
update = {
...update,
account_name: accountName,
};
}
if (username) {
if (!isUsernameValid(username)) {
res.status(400).send({ err: "invalid request" });
return;
}
update = {
...update,
username: username,
};
}
if (calendarMaxFutureBookingDays) {
update = {
...update,
calendar_max_future_booking_days: calendarMaxFutureBookingDays,
};
}
if (calendarMinEarliestBookingTime) {
update = {
...update,
calendar_min_earliest_booking_time: calendarMinEarliestBookingTime,
};
}
if (Object.keys(update).length === 0) {
return res.status(400).send({ err: "invalid request" });
}
// update user
await User.update(update, {
where: {
user_id: userId,
},
})
.then(() => {
res.status(200).send({ msg: "success" });
})
.catch((err) => {
logger.error(err);
res.status(500).send({ err: "invalid request" });
});
} catch (error) {
logger.error(error);
res.status(500).send({ err: "invalid request" });
}
}
export async function DeleteEmployee(req: Request, res: Response) {
try {
let { userId } = req.body;
// validate request
if (!userId) {
return res.status(400).send({ err: "invalid request" });
}
// verify if requester is a store master
const requesterSession = await getUserSession(req);
if (!requesterSession) {
logger.debug("Requester session not found");
return res.status(401).send({ err: "unauthorized" });
}
const store = await Store.findOne({
where: {
owner_user_id: requesterSession.user_id,
},
});
if (!store) {
logger.debug("Store not found");
return res.status(400).send({ err: "invalid request" });
}
// check if user exists
const existingUser = await User.findOne({
where: {
user_id: userId,
},
});
if (!existingUser) {
logger.debug("User not found");
return res.status(400).send({ err: "invalid request" });
}
User.destroy({
where: {
user_id: userId,
},
})
.then(() => {
// delete user
res.status(200).send({ msg: "success" });
})
.catch((err) => {
logger.error(err);
res.status(500).send({ err: "invalid request" });
});
} catch (error) {
logger.error(error);
res.status(500).send({ err: "invalid request" });
}
}