import { BadRequestException, Injectable } from "@nestjs/common"; import slugify from "slugify"; import { In } from "typeorm"; import { AdminMessage, AdsMessage, UserMessage } from "../../../common/enums/message.enum"; import { PaginationUtils } from "../../utils/providers/pagination.utils"; import { PasswordService } from "../../utils/providers/password.service"; import { CreateAdminDto } from "../DTO/create-admin.dto"; import { CreateRoleDto } from "../DTO/create-role.dto"; import { SearchAdminQueryDto } from "../DTO/search-admins-query.dto"; import { SearchRolesQueryDto } from "../DTO/search-roles.dto"; import { PermissionsRepository } from "../repositories/permissions.repository"; import { RoleRepository } from "../repositories/roles.repository"; import { UserRepository } from "../repositories/users.repository"; @Injectable() export class AdminsService { constructor( private readonly userRepository: UserRepository, private readonly rolesRepository: RoleRepository, private readonly permissionsRepository: PermissionsRepository, private readonly passwordService: PasswordService, ) {} async createAdmin(createDto: CreateAdminDto) { const existEmail = await this.userRepository.findOneBy({ email: createDto.email }); if (existEmail) throw new BadRequestException(UserMessage.EMAIL_EXIST); const existPhone = await this.userRepository.findOneBy({ phone: createDto.phone }); if (existPhone) throw new BadRequestException(UserMessage.PHONE_EXIST); const role = await this.rolesRepository.findOne({ where: { id: createDto.roleId }, relations: { permissions: true } }); if (!role) throw new BadRequestException(AdsMessage.ROLE_NOT_FOUND); await this.rolesRepository.save(role); if (createDto.password !== createDto.repeatPassword) throw new BadRequestException(AdminMessage.PASSWORD_NOT_MATCH); const hashedPassword = await this.passwordService.hashPassword(createDto.password); const userName = slugify(`${createDto.firstName} ${Date.now().toString().slice(-5)}`, { lower: true, trim: true }); const adminUser = this.userRepository.create({ ...createDto, roles: [role], password: hashedPassword, userName }); await this.userRepository.save(adminUser); return { message: AdminMessage.ADMIN_CREATED, adminUser, }; } /************************************************************ */ async createRole(createDto: CreateRoleDto) { const existRole = await this.rolesRepository.findOne({ where: { name: createDto.name } }); if (existRole) throw new BadRequestException(AdminMessage.ROLE_EXIST); const permissions = await this.permissionsRepository.findBy({ id: In(createDto.permissions) }); if (permissions.length !== createDto.permissions.length) throw new BadRequestException(AdminMessage.PERMISSIONS_NOT_FOUND); const role = this.rolesRepository.create({ ...createDto, permissions, isAdmin: true }); await this.rolesRepository.save(role); return { message: AdminMessage.ROLE_CREATED, role, }; } /************************************************************ */ async getAdmins(queryDto: SearchAdminQueryDto) { const [users, count] = await this.userRepository.getAdmins(queryDto); return { users, count, paginate: true, }; } /************************************************************ */ async getPermissions() { const permissions = await this.permissionsRepository.find({ select: { id: true, name: true } }); return { permissions, }; } /************************************************************ */ async getAdminPermissions(userId: string) { const user = await this.userRepository.findOne({ where: { id: userId }, relations: { roles: { permissions: true } } }); if (!user) throw new BadRequestException(UserMessage.USER_NOT_FOUND); return { permissions: user.roles[0].permissions, }; } /************************************************************ */ async getRoles(queryDto: SearchRolesQueryDto) { const { limit, skip } = PaginationUtils(queryDto); const queryBuilder = this.rolesRepository.createQueryBuilder("role"); queryBuilder .where("role.isAdmin = :isAdmin", { isAdmin: true }) // .leftJoinAndSelect("role.permissions", "permissions") .loadRelationCountAndMap("role.userCount", "role.users"); if (queryDto.q) { queryBuilder.andWhere("role.name ILIKE :q", { q: `%${queryDto.q}%` }); } queryBuilder.take(limit).skip(skip).orderBy("role.createdAt", "DESC"); const [roles, count] = await queryBuilder.getManyAndCount(); return { roles, count, paginate: true, }; } }