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, language: "en", // TODO: get language from request analytics_enabled: true, }) .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" }); } }