From 4c7e49fb9ad7b22d47811b6aa9f8c2f19ba29a7f Mon Sep 17 00:00:00 2001 From: Henrriky Date: Tue, 12 Mar 2024 12:46:12 -0300 Subject: [PATCH] feat: add base structure to EL-IAM integration --- ESPACO-LAZER-IAM.MD | 38 +++ backend/src/controllers/IAMControllerEL.ts | 314 +++++++++++++++++++++ backend/src/routes/iamRoutesEL.ts | 23 ++ backend/src/routes/index.ts | 2 + 4 files changed, 377 insertions(+) create mode 100644 ESPACO-LAZER-IAM.MD create mode 100644 backend/src/controllers/IAMControllerEL.ts create mode 100644 backend/src/routes/iamRoutesEL.ts diff --git a/ESPACO-LAZER-IAM.MD b/ESPACO-LAZER-IAM.MD new file mode 100644 index 0000000..d24ba28 --- /dev/null +++ b/ESPACO-LAZER-IAM.MD @@ -0,0 +1,38 @@ +# O que fazer? + +- Quando um usuário for criado na plataforma do E-trust Horacius, a aplicação do Omnihit deve criar o mesmo usuário no Banco de Dados do Omnihit. + - Criação + - Atualização + - Exclusão +- Quando um usuário for criado com um **profile(role)**, a aplicação do Omnihit deve alterar o profile + - Tipos de roles: `admin`, `user`, `supervisor` + - Atualização + - Exclusão + +# Como fazer? + +- Elaborar forma de autenticação +- Criar uma aplicação REST seguindo o protocolo especificado na documentação do Horacius + - Níveis + - 1: Da para fazer + - 2: Tem que analisar + - Users + - [] CheckUser (1) + - [] CreateUser (1) + - [] DeleteUser (1) + - [] UpdateUser (1) + - [] ListAllUsers **OPCIONAL** + - [] LockUser (2) + - [] UnlockUser (2) + - [] ResetPassword (2) + - Rights + - [] CheckUserRight (1) + - [] CreateRight (1) + - [] UpdateRight (1) + - [] DeleteRight (1) + - [] GetAllRights **OPCIONAL** + - Users X Rights + - [] LinkUserAndUserRight (1) + - [] UnlinkUserAndUserRight (1) + - [] GetAllUserRights **OPCIONAL** + diff --git a/backend/src/controllers/IAMControllerEL.ts b/backend/src/controllers/IAMControllerEL.ts new file mode 100644 index 0000000..afcdc76 --- /dev/null +++ b/backend/src/controllers/IAMControllerEL.ts @@ -0,0 +1,314 @@ +import { Request, Response } from "express"; +import { getIO } from "../libs/socket"; + +import AppError from "../errors/AppError"; + +import CreateUserService from "../services/UserServices/CreateUserService"; +import ListUsersService from "../services/UserServices/ListUsersService"; +import UpdateUserService from "../services/UserServices/UpdateUserService"; +import ShowUserService from "../services/UserServices/ShowUserService"; +import DeleteUserService from "../services/UserServices/DeleteUserService"; + +import ListUser from "../services/UserServices/ListUserParamiterService"; +import { del, get, set } from "../helpers/RedisClient"; + +import { + startWhoIsOnlineMonitor, + stopWhoIsOnlineMonitor +} from "../helpers/WhoIsOnlineMonitor"; + +import { format, subMonths } from "date-fns"; +import { ptBR } from "date-fns/locale"; +import CountTicketsByUserQueue from "../services/UserServices/CountTicketsByUserQueue"; +import { splitDateTime } from "../helpers/SplitDateTime"; +import ListUserByWhatsappQueuesService from "../services/UserServices/ListUserByWhatsappQueuesService"; +import { getSettingValue } from "../helpers/WhaticketSettings"; +import { setBotInfo } from "../helpers/SetBotInfo"; + +type IndexQuery = { + searchParam: string; + pageNumber: string; + profile?: string; + userId: string; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { searchParam, pageNumber, profile } = req.query as IndexQuery; + + const { users, count, hasMore } = await ListUsersService({ + searchParam, + pageNumber, + profile + }); + + if (req.user.profile !== "master") { + let auxUsers: Array = []; + + // for (var user of users) { + // if (user.profile !== 'master') { + // auxUsers.push(user) + // } + // } + + for (var user of users) { + if (user.profile !== "master") { + if (req.user.profile == "supervisor" && user.profile == "admin") + continue; + + auxUsers.push(user); + } + } + + return res.json({ users: auxUsers, count, hasMore }); + } + + return res.json({ users, count, hasMore }); + + // const { users, count, hasMore } = await ListUsersService({ + // searchParam, + // pageNumber + // }); + + // if(req.user.profile!=='master'){ + + // let auxUsers: Array = []; + + // for (var user of users) { + // if(user.profile!=='master'){ + // auxUsers.push(user) + // } + // } + + // return res.json({ users: auxUsers, count, hasMore }); + // } + + // return res.json({ users, count, hasMore }); +}; + +export const all = async (req: Request, res: Response): Promise => { + let { userId, profile }: any = req.query as IndexQuery; + + console.log( + "userId: ", + userId, + " | profile: ", + profile, + ' | getSettingValue("queueTransferByWhatsappScope")?.value: ', + getSettingValue("queueTransferByWhatsappScope")?.value + ); + + if (getSettingValue("queueTransferByWhatsappScope")?.value == "enabled") { + if (!userId) return res.json({ users: [], queues: [] }); + + const obj = await ListUserByWhatsappQueuesService( + userId, + '"admin", "user", "supervisor"' + ); + + const usersByWhatsqueue = obj.users; + const queues = obj.queues; + + let userIds = usersByWhatsqueue.map((w: any) => w.userId); + + const users = await ListUser({ + userIds + }); + + return res.json({ users, queues }); + } else { + const users = await ListUser({ + profile + }); + return res.json({ users }); + } +}; + +export const store = async (req: Request, res: Response): Promise => { + const { email, password, name, profile, positionCompany, queueIds } = + req.body; + + console.log("===========> req.url: ", req.url); + + if ( + req.url === "/user" && + getSettingValue("userCreation")?.value == "disabled" && + req.user.profile == "admin" + ) { + throw new AppError("ERR_NO_PERMISSION", 403); + } else if ( + req.url === "/signup" && + getSettingValue("userCreation")?.value == "disabled" + ) { + throw new AppError("ERR_USER_CREATION_DISABLED", 403); + } else if (req.user.profile !== "master") { + throw new AppError("ERR_NO_PERMISSION", 403); + } + + const user = await CreateUserService({ + email, + password, + name, + positionCompany, + profile, + queueIds + }); + + if (user) { + const { id, name } = user; + await set(`user:${id}`, { id, name }); + } + + const io = getIO(); + io.emit("user", { + action: "create", + user + }); + + // await stopWhoIsOnlineMonitor() + await startWhoIsOnlineMonitor(); + + return res.status(200).json(user); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { userId } = req.params; + + const user = await ShowUserService(userId); + + return res.status(200).json(user); +}; + +export const logoutUser = async ( + req: Request, + res: Response +): Promise => { + const { userId } = req.params; + + await stopWhoIsOnlineMonitor(); + + let onlineTime = { + userId: userId, + status: "logout..." + }; + + const io = getIO(); + io.emit("onlineStatus", { + action: "logout", + userOnlineTime: onlineTime + }); + + await startWhoIsOnlineMonitor(); + // + + return res.status(200).json({}); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + if ( + req.user.profile !== "admin" && + req.user.profile !== "master" && + req.user.profile !== "supervisor" + ) { + throw new AppError("ERR_NO_PERMISSION", 403); + } + + const { userId } = req.params; + const userData = req.body; + + const dateToday = splitDateTime( + new Date(format(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: ptBR })) + ); + + const currentDate = new Date(); + const tenMonthsAgo = subMonths(currentDate, 10); + const formattedDate = format(tenMonthsAgo, "yyyy-MM-dd"); + console.log("dateToday.fullDate: ", dateToday.fullDate); + console.log("formattedDate 10 months ago: ", formattedDate); + + const openByUserOnQueue: any[] = await CountTicketsByUserQueue({ + startDate: formattedDate, + endDate: dateToday.fullDate, + status: "open", + clientChatStart: true, + userId: userId + }); + + // console.log('------> openByUserOnQueue: ', openByUserOnQueue) + // console.log() + // console.log('------> 1 userData.queueIds: ', userData.queueIds) + + let userQueuesAttendance = []; + + if ((openByUserOnQueue && openByUserOnQueue.length) > 0) { + userQueuesAttendance = openByUserOnQueue.filter( + (e: any) => !userData.queueIds.includes(e.queueId) + ); + + if (userQueuesAttendance && userQueuesAttendance.length > 0) { + const queueInAttendance = userQueuesAttendance.map(e => e.queueId); + + const mergedSet = new Set([...userData.queueIds, ...queueInAttendance]); + + // Convert the Set back to an array + userData.queueIds = Array.from(mergedSet); + + // console.log('------> 2 userData.queueIds: ', userData.queueIds) + } + } + + let user: any = await UpdateUserService({ userData, userId }); + + await setBotInfo(user); + + if (user) { + const { id, name } = user; + await set(`user:${id}`, { id, name }); + } + + const io = getIO(); + io.emit("user", { + action: "update", + user + }); + + user.userQueuesAttendance = userQueuesAttendance; + + return res.status(200).json(user); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + const { userId } = req.params; + + if (req.user.profile !== "master") { + throw new AppError("ERR_NO_PERMISSION", 403); + } + + await DeleteUserService(userId); + + del(`user:${userId}`); + + const io = getIO(); + io.emit("user", { + action: "delete", + userId + }); + + //test del + await stopWhoIsOnlineMonitor(); + + io.emit("onlineStatus", { + action: "delete", + userOnlineTime: userId + }); + + await startWhoIsOnlineMonitor(); + // + + return res.status(200).json({ message: "User deleted" }); +}; diff --git a/backend/src/routes/iamRoutesEL.ts b/backend/src/routes/iamRoutesEL.ts new file mode 100644 index 0000000..7c359d5 --- /dev/null +++ b/backend/src/routes/iamRoutesEL.ts @@ -0,0 +1,23 @@ +import { Router } from "express"; + +import isAuth from "../middleware/isAuth"; +import * as IAMControllerEL from "../controllers/IAMControllerEL"; + +const iamRoutesEL = Router(); + + +iamRoutesEL.get("/users/all", isAuth, IAMControllerEL.all); + +iamRoutesEL.get("/users", isAuth, IAMControllerEL.index); + +iamRoutesEL.post("/users", isAuth, IAMControllerEL.store); + +iamRoutesEL.put("/users/:userId", isAuth, IAMControllerEL.update); + +iamRoutesEL.get("/users/:userId", isAuth, IAMControllerEL.show); + +iamRoutesEL.get("/users/logout/:userId", isAuth, IAMControllerEL.logoutUser); + +iamRoutesEL.delete("/users/:userId", isAuth, IAMControllerEL.remove); + +export default iamRoutesEL; diff --git a/backend/src/routes/index.ts b/backend/src/routes/index.ts index 297e954..1e769a5 100644 --- a/backend/src/routes/index.ts +++ b/backend/src/routes/index.ts @@ -14,10 +14,12 @@ import reportRoutes from "./reportRoutes"; import schedulingNotifiyRoutes from "./SchedulingNotifyRoutes"; import statusChatEndRoutes from "./statusChatEndRoutes"; import wbotMonitorRoutes from "./wbotMonitorRoutes"; +import iamRoutesEL from "./iamRoutesEL"; const routes = Router(); +routes.use(iamRoutesEL); routes.use(userRoutes); routes.use("/auth", authRoutes); routes.use(settingRoutes);