import { Request, Response } from "express"; import logger from "../logger/logger"; import User from "../models/user"; import { isAccountNameValid, isPasswordValid, isUsernameValid, } from "../validator/validator"; import { CALENDAR_MAX_FUTURE_BOOKING_DAYS, CALENDAR_MAX_SERVICE_DURATION, CALENDAR_MIN_EARLIEST_BOOKING_TIME, CALENDAR_USING_PRIMARY_CALENDAR, Roles, } from "../utils/constants"; import { decodeBase64, getUserSession, hashPassword, matchPassword, newStoreId, newUserId, saveSession, } from "../utils/utils"; import Store from "../models/store"; export async function SignUp(req: Request, res: Response) { try { let { username, accountName, password } = req.body; // validate request if (!username || !accountName || !password) { return res.status(400).send({ err: "invalid request" }); } if (!isUsernameValid(username)) { return res.status(400).send({ err: "invalid request" }); } if (!isAccountNameValid(accountName)) { return res.status(400).send({ err: "invalid request" }); } accountName = accountName.toLowerCase(); // 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 store let userId = newUserId(); Store.create({ store_id: newStoreId(), owner_user_id: userId, name: username, calendar_max_future_booking_days: CALENDAR_MAX_FUTURE_BOOKING_DAYS, calendar_min_earliest_booking_time: CALENDAR_MIN_EARLIEST_BOOKING_TIME, calendar_using_primary_calendar: CALENDAR_USING_PRIMARY_CALENDAR, calendar_max_service_duration: CALENDAR_MAX_SERVICE_DURATION, }) .then(async (store) => { logger.debug( "Store created with storeId: %s storeName: %s", store.store_id, store.name ); // create user await User.create({ user_id: userId, store_id: store.store_id, role: Roles.Master, account_name: accountName, username: username, password: hashedPassword, }) .then((user) => { logger.debug( "User created with accountName: %s username: %s", user.account_name, user.username ); // create session saveSession(res, user.user_id, user.username); }) .catch((err) => { logger.error(err); res.status(500).send({ err: "invalid request" }); }); }) .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 Login(req: Request, res: Response) { try { let { accountName, password } = req.body; // validate request if (!accountName || !password) { return res.status(400).send({ err: "invalid request" }); } accountName = accountName.toLowerCase(); if (!isAccountNameValid(accountName)) { return res.status(400).send({ err: "invalid request" }); } // check if user exists const user = await User.findOne({ where: { account_name: accountName, }, }); if (!user) { logger.debug( "User does not exist 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" }); } // compare password const match = await matchPassword(decodedPassword, user.password); if (!match) { logger.debug("Password is not valid"); return res.status(400).send({ err: "invalid request" }); } // create session saveSession(res, user.user_id, user.username); } catch (error) { logger.error(error); res.status(500).send({ err: "invalid request" }); } } export async function Logout(req: Request, res: Response) { try { const session = await getUserSession(req); if (!session) { return res.status(401).send({ err: "unauthorized" }); } await session.destroy(); res.status(200).send({ msg: "logout successful" }); } catch (error) { logger.error(error); res.status(500).send({ err: "invalid request" }); } } export async function GetUser(req: Request, res: Response) { try { const session = await getUserSession(req); if (!session) { return res.status(401).send({ err: "unauthorized" }); } const user = await User.findOne({ where: { user_id: session.user_id, }, attributes: ["user_id", "username"], }); if (!user) { return res.status(401).send({ err: "unauthorized" }); } const stores = await Store.findAll({ where: { owner_user_id: user.user_id, }, attributes: ["store_id", "name"], }); res.status(200).send({ user, stores }); } catch (error) { logger.error(error); res.status(500).send({ err: "invalid request" }); } } export async function IsAccountNameAvailable(req: Request, res: Response) { try { let { accountName } = req.body; // validate request if (!accountName) { return res.status(400).send({ err: "invalid request" }); } accountName = accountName.toLowerCase(); if (!isAccountNameValid(accountName)) { return res.status(400).send({ err: "invalid request" }); } // check if user exists const user = await User.findOne({ where: { account_name: accountName, }, }); if (user) { logger.debug( "User already exists with this accountName: %s", accountName ); return res.status(400).send({ err: "invalid request" }); } res.status(200).send({ msg: "account name available" }); } catch (error) { logger.error(error); res.status(500).send({ err: "invalid request" }); } }