Compare commits

..

No commits in common. "37c384a7124f0a66c7e939529d915743358ea0d5" and "4c7e49fb9ad7b22d47811b6aa9f8c2f19ba29a7f" have entirely different histories.

8 changed files with 284 additions and 531 deletions

View File

@ -21,10 +21,10 @@
- [] CreateUser (1) - [] CreateUser (1)
- [] DeleteUser (1) - [] DeleteUser (1)
- [] UpdateUser (1) - [] UpdateUser (1)
- [ ] ResetPassword (1) - [] ListAllUsers **OPCIONAL**
- [] LockUser (2) - [] LockUser (2)
- [] UnlockUser (2) - [] UnlockUser (2)
- [ ] ListAllUsers **OPCIONAL** - [] ResetPassword (2)
- Rights - Rights
- [] CheckUserRight (1) - [] CheckUserRight (1)
- [] CreateRight (1) - [] CreateRight (1)
@ -36,47 +36,3 @@
- [] UnlinkUserAndUserRight (1) - [] UnlinkUserAndUserRight (1)
- [] GetAllUserRights **OPCIONAL** - [] GetAllUserRights **OPCIONAL**
# Atribuições
- Henrriky
- [ ] Verify token middleware
- [X] CheckUser (1)
- [ ] Routes
- [X] Controller
- [X] Service
- [X] Error handling
- [X] CreateUser (1)
- [ ] Routes
- [X] Controller
- [X] Service
- [X] Error handling
- [X] DeleteUser (1)
- [ ] Routes
- [X] Controller
- [X] Service
- [X] Error handling
- [X] UpdateUser (1)
- [ ] Routes
- [X] Controller
- [X] Service
- [X] Error handling
- [X] ResetPassword (1)
- [ ] Routes
- [X] Controller
- [X] Service
- [X] Error handling
- [X] LinkUserAndUserRight (1)
- [ ] Routes
- [X] Controller
- [X] Service
- [X] Error handling
- [X] UnlinkUserAndUserRight (1)
- [ ] Routes
- [X] Controller
- [X] Service
- [X] Error handling
- [X] CheckUserRight (1)
- [ ] Routes
- [X] Controller
- [X] Service
- [X] Error handling

View File

@ -24,26 +24,133 @@ import { splitDateTime } from "../helpers/SplitDateTime";
import ListUserByWhatsappQueuesService from "../services/UserServices/ListUserByWhatsappQueuesService"; import ListUserByWhatsappQueuesService from "../services/UserServices/ListUserByWhatsappQueuesService";
import { getSettingValue } from "../helpers/WhaticketSettings"; import { getSettingValue } from "../helpers/WhaticketSettings";
import { setBotInfo } from "../helpers/SetBotInfo"; import { setBotInfo } from "../helpers/SetBotInfo";
import { logger } from "../utils/logger";
import ResetPasswordService from "../services/UserServices/ResetPassword";
import CheckUserRightService from "../services/UserServices/CheckUserRightService";
import UnlinkUserRightService from "../services/UserServices/UnlinkUserRight";
import LinkUserRightService from "../services/UserServices/LinkUserRight";
interface IAMResponse { type IndexQuery = {
return_code: string searchParam: string;
return_msg: string pageNumber: string;
profile?: string;
userId: string;
};
export const index = async (req: Request, res: Response): Promise<Response> => {
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<object> = [];
// 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<object> = [];
// 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<Response> => {
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<Response> => {
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);
} }
//TODO: REVIEW CREATE USER
export const createUser = async (req: Request, res: Response<IAMResponse & { user_created: "1" | "0" }>): Promise<Response> => {
try {
const { user_id, user_first_name, user_tax_id } = req.body;
//user_id ou cria uma tabela nova ou um atributo novo
const user = await CreateUserService({ const user = await CreateUserService({
email: user_tax_id, email,
password: "padrao", password,
name: user_first_name, name,
positionCompany,
profile,
queueIds
}); });
if (user) { if (user) {
@ -57,150 +164,103 @@ export const createUser = async (req: Request, res: Response<IAMResponse & { use
user user
}); });
// await stopWhoIsOnlineMonitor()
await startWhoIsOnlineMonitor(); await startWhoIsOnlineMonitor();
return res.status(204).json({ return res.status(200).json(user);
return_code: "204",
return_msg: `User ${user_id} created`,
user_created: "1"
});
} catch (error) {
if (error instanceof AppError) {
logger.warn(error);
return res.status(error.statusCode).json({
return_code: String(error.statusCode),
return_msg: error.message,
user_created: "0",
});
}
return res.status(500).json({
return_code: "500",
return_msg: "Internal server error",
user_created: "0",
});
}
}; };
export const checkUser = async (req: Request, res: Response<IAMResponse & { user_exists: "1" | "0" }>): Promise<Response> => { export const show = async (req: Request, res: Response): Promise<Response> => {
try { const { userId } = req.params;
const { user_id } = req.body;
await ShowUserService(user_id);
return res.status(200).json({
return_code: "200",
return_msg: "",
user_exists: "1"
});
} catch (error) {
if (error instanceof AppError) { const user = await ShowUserService(userId);
logger.warn(error);
return res.status(error.statusCode).json({
return_code: String(error.statusCode),
return_msg: error.message,
user_exists: "0",
});
}
return res.status(500).json({ return res.status(200).json(user);
return_code: "500",
return_msg: "Internal server error",
user_exists: "0",
});
}
}; };
//TODO: REVIEW DELETE USER export const logoutUser = async (
export const deleteUser = async (req: Request, res: Response<IAMResponse & { user_removed: "1" | "0" }>): Promise<Response> => { req: Request,
try { res: Response
const { user_id } = req.body; ): Promise<Response> => {
const { userId } = req.params;
await DeleteUserService(user_id);
del(`user:${user_id}`);
const io = getIO();
io.emit("user", {
action: "delete",
user_id
});
//test del
await stopWhoIsOnlineMonitor(); await stopWhoIsOnlineMonitor();
let onlineTime = {
userId: userId,
status: "logout..."
};
const io = getIO();
io.emit("onlineStatus", { io.emit("onlineStatus", {
action: "delete", action: "logout",
userOnlineTime: user_id userOnlineTime: onlineTime
}); });
await startWhoIsOnlineMonitor(); await startWhoIsOnlineMonitor();
return res.status(200).json({ //
return_code: "200",
return_msg: `User ${user_id} deleted`,
user_removed: "1",
});
} catch (error) { return res.status(200).json({});
if (error instanceof AppError) {
logger.warn(error);
return res.status(error.statusCode).json({
return_code: String(error.statusCode),
return_msg: error.message,
user_removed: "0",
});
}
return res.status(500).json({
return_code: "500",
return_msg: "Internal server error",
user_removed: "0",
});
}
}; };
//TODO: REVIEW UPDATE USER export const update = async (
export const updateUser = async (req: Request, res: Response<IAMResponse & { user_updated: "1" | "0" }>): Promise<Response> => { req: Request,
try { res: Response
const { user_id, user_first_name, user_tax_id } = req.body; ): Promise<Response> => {
// const dateToday = splitDateTime(new Date(format(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: ptBR }))); if (
// const currentDate = new Date(); req.user.profile !== "admin" &&
// const tenMonthsAgo = subMonths(currentDate, 10); req.user.profile !== "master" &&
// const formattedDate = format(tenMonthsAgo, "yyyy-MM-dd"); req.user.profile !== "supervisor"
// console.log("dateToday.fullDate: ", dateToday.fullDate); ) {
// console.log("formattedDate 10 months ago: ", formattedDate); throw new AppError("ERR_NO_PERMISSION", 403);
// const openByUserOnQueue: any[] = await CountTicketsByUserQueue({
// startDate: formattedDate,
// endDate: dateToday.fullDate,
// status: "open",
// clientChatStart: true,
// userId: userId
// });
// 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]);
// userData.queueIds = Array.from(mergedSet);
// }
// }
const userData = {
email: user_tax_id,
name: user_first_name,
} }
// email?: string;
// name?: string; const { userId } = req.params;
// password?: string; const userData = req.body;
// positionCompany?: string;
// profile?: string; const dateToday = splitDateTime(
// queueIds?: number[]; new Date(format(new Date(), "yyyy-MM-dd HH:mm:ss", { locale: ptBR }))
let user: any = await UpdateUserService({ userData, userId: user_id }); );
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); await setBotInfo(user);
if (user) { if (user) {
@ -214,154 +274,41 @@ export const updateUser = async (req: Request, res: Response<IAMResponse & { use
user user
}); });
// user.userQueuesAttendance = userQueuesAttendance; user.userQueuesAttendance = userQueuesAttendance;
return res.status(200).json({
return_code: "200",
return_msg: `User ${user_id} updated`,
user_updated: "1"
});
} catch (error) {
if (error instanceof AppError) {
logger.warn(error);
return res.status(error.statusCode).json({
return_code: String(error.statusCode),
return_msg: error.message,
user_updated: "0",
});
}
return res.status(500).json({ return res.status(200).json(user);
return_code: "500",
return_msg: "Internal server error",
user_updated: "0",
});
}
}; };
export const resetPassword = async (req: Request, res: Response<IAMResponse & { password_set: "1" | "0" }>): Promise<Response> => { export const remove = async (
try { req: Request,
const { user_id, user_password } = req.body; res: Response
): Promise<Response> => {
const { userId } = req.params;
await ResetPasswordService({ if (req.user.profile !== "master") {
userPassword: user_password, throw new AppError("ERR_NO_PERMISSION", 403);
userId: user_id
})
return res.status(200).json({
return_code: "200",
return_msg: `User has the password changed`,
password_set: "1"
});
} catch (error) {
if (error instanceof AppError) {
logger.warn(error);
return res.status(error.statusCode).json({
return_code: String(error.statusCode),
return_msg: error.message,
password_set: "0",
});
} }
return res.status(500).json({ await DeleteUserService(userId);
return_code: "500",
return_msg: "Internal server error",
password_set: "0",
});
}
}; del(`user:${userId}`);
export const linkUserRight = async (req: Request, res: Response<IAMResponse & { user_right_linked: "1" | "0" }>): Promise<Response> => { const io = getIO();
try { io.emit("user", {
const { user_id, user_right_title, } = req.body; action: "delete",
userId
await LinkUserRightService({ });
userProfile: user_right_title,
userId: user_id //test del
}) await stopWhoIsOnlineMonitor();
return res.status(200).json({ io.emit("onlineStatus", {
return_code: "200", action: "delete",
return_msg: `User ${user_id} associated`, userOnlineTime: userId
user_right_linked: "1" });
});
} catch (error) { await startWhoIsOnlineMonitor();
if (error instanceof AppError) { //
logger.warn(error);
return res.status(error.statusCode).json({ return res.status(200).json({ message: "User deleted" });
return_code: String(error.statusCode),
return_msg: error.message,
user_right_linked: "0",
});
}
return res.status(500).json({
return_code: "500",
return_msg: "Internal server error",
user_right_linked: "0",
});
}
};
export const unlinkUserRight = async (req: Request, res: Response<IAMResponse & { user_right_unlinked: "1" | "0" }>): Promise<Response> => {
try {
const { user_id, user_right_title } = req.body;
await UnlinkUserRightService({
userProfile: user_right_title,
userId: user_id
})
return res.status(200).json({
return_code: "200",
return_msg: `User ${user_id} deassociated`,
user_right_unlinked: "1",
});
} catch (error) {
if (error instanceof AppError) {
logger.warn(error);
return res.status(error.statusCode).json({
return_code: String(error.statusCode),
return_msg: error.message,
user_right_unlinked: "0",
});
}
return res.status(500).json({
return_code: "500",
return_msg: "Internal server error",
user_right_unlinked: "0",
});
}
};
export const checkUserRight = async (req: Request, res: Response<IAMResponse & { user_right_exists: "1" | "0" }>): Promise<Response> => {
try {
const { user_id, user_right_title } = req.body;
const userHasRight = await CheckUserRightService({
userProfileToCompare: user_right_title,
userId: user_id
})
return res.status(200).json({
return_code: "200",
return_msg: "",
user_right_exists: userHasRight ? "1" : "0",
});
} catch (error) {
if (error instanceof AppError) {
logger.warn(error);
return res.status(error.statusCode).json({
return_code: String(error.statusCode),
return_msg: error.message,
user_right_exists: "0",
});
}
return res.status(500).json({
return_code: "500",
return_msg: "Internal server error",
user_right_exists: "0",
});
}
}; };

View File

@ -1,23 +0,0 @@
import { Request, Response, NextFunction } from "express";
import AppError from "../errors/AppError";
const verifyAPIKey = (req: Request, res: Response, next: NextFunction): void => {
const authHeader = req.headers.authorization;
if (!authHeader) {
throw new AppError("ERR_SESSION_EXPIRED", 401);
}
const [, token] = authHeader.split(" ");
const apiKeyIsValid = token === process.env.TOKEN_REMOTE_TICKET_CREATION
if (!apiKeyIsValid) {
throw new AppError(
"Invalid token",
401
);
}
return next();
};
export default verifyAPIKey;

View File

@ -1,19 +1,23 @@
import { Router } from "express"; import { Router } from "express";
import isAuth from "../middleware/isAuth";
import * as IAMControllerEL from "../controllers/IAMControllerEL"; import * as IAMControllerEL from "../controllers/IAMControllerEL";
import verifyAPIKey from "../middleware/verifyAPIKey";
const iamRoutesEL = Router(); const iamRoutesEL = Router();
iamRoutesEL.post("/IAM/users", verifyAPIKey, IAMControllerEL.createUser);
iamRoutesEL.put("/IAM/users", verifyAPIKey, IAMControllerEL.updateUser);
iamRoutesEL.delete("/IAM/users", verifyAPIKey, IAMControllerEL.deleteUser);
iamRoutesEL.get("/IAM/users/check", verifyAPIKey, IAMControllerEL.checkUser);
iamRoutesEL.patch("/IAM/users/rights/link", verifyAPIKey, IAMControllerEL.linkUserRight); iamRoutesEL.get("/users/all", isAuth, IAMControllerEL.all);
iamRoutesEL.patch("/IAM/users/rights/unlink", verifyAPIKey, IAMControllerEL.unlinkUserRight);
iamRoutesEL.post("/IAM/users/rights/check", verifyAPIKey, IAMControllerEL.checkUserRight);
iamRoutesEL.patch("/IAM/users/reset-password", verifyAPIKey, IAMControllerEL.resetPassword); 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; export default iamRoutesEL;

View File

@ -1,33 +0,0 @@
import * as Yup from "yup";
import AppError from "../../errors/AppError";
import ShowUserService from "./ShowUserService";
interface CheckUserRightServiceRequest {
userProfileToCompare: string;
userId: string | number;
}
type CheckUserRightServiceResponse = boolean;
const CheckUserRightService = async ({userProfileToCompare, userId}: CheckUserRightServiceRequest): Promise<CheckUserRightServiceResponse> => {
try {
const user = await ShowUserService(userId);
const schema = Yup.object().shape({
userId: Yup.string().required(),
userProfile: Yup.string().oneOf(['admin', 'user', 'supervisor', 'master']).required()
});
try {
await schema.validate({ userId, userProfile: userProfileToCompare });
} catch (err: any) {
throw new AppError(err.message);
}
return (user.profile == userProfileToCompare) ? true : false
} catch (error: any) {
console.error('===> Error on CheckUserRightService.ts file: \n', error)
throw new AppError(error.message);
}
};
export default CheckUserRightService;

View File

@ -1,33 +0,0 @@
import * as Yup from "yup";
import AppError from "../../errors/AppError";
import ShowUserService from "./ShowUserService";
interface LinkUserRightServiceRequest {
userProfile: string;
userId: string | number;
}
const LinkUserRightService = async ({userProfile, userId}: LinkUserRightServiceRequest): Promise<void> => {
try {
const user = await ShowUserService(userId);
const schema = Yup.object().shape({
userId: Yup.string().required(),
userProfile: Yup.string().oneOf(['admin', 'user', 'supervisor']).required()
});
try {
await schema.validate({ userId, userProfile });
} catch (err: any) {
throw new AppError(err.message);
}
await user.update({
profile: userProfile
});
await user.reload();
} catch (error: any) {
console.error('===> Error on LinkUserRightService.ts file: \n', error)
throw new AppError(error.message);
}
};
export default LinkUserRightService;

View File

@ -1,32 +0,0 @@
import * as Yup from "yup";
import AppError from "../../errors/AppError";
import ShowUserService from "./ShowUserService";
interface ResetPasswordServiceRequest {
userPassword: string;
userId: string | number;
}
const ResetPasswordService = async ({userPassword, userId}: ResetPasswordServiceRequest): Promise<void> => {
try {
const user = await ShowUserService(userId);
const schema = Yup.object().shape({
password: Yup.string(),
});
try {
await schema.validate({ password: userPassword });
} catch (err: any) {
throw new AppError(err.message);
}
await user.update({
userPassword,
});
await user.reload();
} catch (error: any) {
console.error('===> Error on ResetPasswordService.ts file: \n', error)
throw new AppError(error.message);
}
};
export default ResetPasswordService;

View File

@ -1,33 +0,0 @@
import * as Yup from "yup";
import AppError from "../../errors/AppError";
import ShowUserService from "./ShowUserService";
interface UnlinkUserRightServiceRequest {
userProfile: string;
userId: string | number;
}
const UnlinkUserRightService = async ({userProfile, userId}: UnlinkUserRightServiceRequest): Promise<void> => {
try {
const user = await ShowUserService(userId);
const schema = Yup.object().shape({
userId: Yup.string().required(),
userProfile: Yup.string().oneOf(['user'])
});
try {
await schema.validate({ userId, userProfile });
} catch (err: any) {
throw new AppError(err.message);
}
await user.update({
profile: userProfile || "user"
});
await user.reload();
} catch (error: any) {
console.error('===> Error on UnlinkUserRightService.ts file: \n', error)
throw new AppError(error.message);
}
};
export default UnlinkUserRightService;