import { Body, Controller, Get, Path, Post, Request, Route, Security, Tags } from "tsoa"; import { AppDataSource } from "../database/data-source"; import { RequestWithUser } from "../middlewares/user"; import HttpError from "../interfaces/http-error"; import HttpStatus from "../interfaces/http-status"; import HttpSuccess from "../interfaces/http-success"; import HttpStatusCode from "../interfaces/http-status"; import { AuthRole } from "../entities/AuthRole"; import { AuthRoleAttr } from "../entities/AuthRoleAttr"; import { PosMaster } from "../entities/PosMaster"; import { Profile } from "../entities/Profile"; import { AuthSys } from "../entities/AuthSys"; import { promisify } from "util"; import { In } from "typeorm"; const REDIS_HOST = process.env.REDIS_HOST; const REDIS_PORT = process.env.REDIS_PORT; @Route("api/v1/org/permission") @Tags("Permission") @Security("bearerAuth") export class PermissionController extends Controller { private profileRepo = AppDataSource.getRepository(Profile); private posMasterRepository = AppDataSource.getRepository(PosMaster); private authRoleRepo = AppDataSource.getRepository(AuthRole); private authRoleAttrRepo = AppDataSource.getRepository(AuthRoleAttr); private authSysRepo = AppDataSource.getRepository(AuthSys); private redis = require("redis"); @Get("") public async getPermission(@Request() request: { user: Record }) { const redisClient = await this.redis.createClient({ host: REDIS_HOST, port: REDIS_PORT, }); const getAsync = promisify(redisClient.get).bind(redisClient); let reply = await getAsync("role_" + request.user.sub); if (reply != null) { reply = JSON.parse(reply); } else { const profile = await this.profileRepo.findOne({ select: ["id"], where: { keycloak: request.user.sub }, }); if (!profile) { throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); } const posMaster = await this.posMasterRepository.findOne({ // select: ["authRoleId"], where: { current_holderId: profile.id, orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true, }, }, }); if (!posMaster) { throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลสิทธิ์"); } const getDetail = await this.authRoleRepo.findOne({ select: ["id", "roleName", "roleDescription"], where: { id: posMaster.authRoleId }, }); if (!getDetail) { throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูล"); } const roleAttrData = await this.authRoleAttrRepo.find({ select: [ "authSysId", "parentNode", "attrOwnership", "attrIsCreate", "attrIsList", "attrIsGet", "attrIsUpdate", "attrIsDelete", "attrPrivilege", ], where: { authRoleId: getDetail.id }, }); reply = { ...getDetail, roles: roleAttrData, }; redisClient.setex("role_" + request.user.sub, 86400, JSON.stringify(reply)); } return new HttpSuccess(reply); } @Get("menu") public async listAuthSys(@Request() request: { user: Record }) { const redisClient = await this.redis.createClient({ host: REDIS_HOST, port: REDIS_PORT, }); const getAsync = promisify(redisClient.get).bind(redisClient); let reply = await getAsync("menu_" + request.user.sub); if (reply != null) { reply = JSON.parse(reply); } else { const profile = await this.profileRepo.findOne({ select: ["id"], where: { keycloak: request.user.sub }, }); if (!profile) { throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลบุคคลนี้ในระบบ"); } const posMaster = await this.posMasterRepository.findOne({ // select: ["authRoleId"], where: { current_holderId: profile.id, orgRevision: { orgRevisionIsDraft: false, orgRevisionIsCurrent: true, }, }, }); if (!posMaster) { throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลตำแหน่งในโครงสร้าง"); } const authRole = await this.authRoleRepo.findOne({ select: ["id"], where: { id: posMaster.authRoleId }, }); if (!authRole) { throw new HttpError(HttpStatus.NOT_FOUND, "ไม่พบข้อมูลสิทธิ์"); } const roleAttrData = await this.authRoleAttrRepo.find({ select: ["authSysId", "parentNode"], where: { authRoleId: authRole.id, attrIsList: true }, }); const parentNode = roleAttrData.map((x) => x.parentNode); const authSysId = roleAttrData.map((x) => x.authSysId); const sysId = parentNode.concat(authSysId); const getList = await this.authSysRepo.find({ select: ["id", "parentId", "sysName", "sysDescription", "icon", "path", "order"], where: { id: In(sysId), }, }); reply = getList .filter((x) => x.parentId == null) .map((item) => { return { ...item, children: getList .filter((x) => x.parentId == item.id) .sort((a, b) => a.order - b.order), }; }) .sort((a, b) => a.order - b.order); redisClient.setex("menu_" + request.user.sub, 86400, JSON.stringify(reply)); } return new HttpSuccess(reply); } }