import { CanActivate, ExecutionContext, Injectable, HttpStatus, } from '@nestjs/common'; import { BadRequestException, NotFoundException } from '@nestjs/common'; import { UserRepository } from '@app/common/modules/user/repositories'; import { DeviceRepository } from '@app/common/modules/device/repositories'; import { PermissionType } from '@app/common/constants/permission-type.enum'; @Injectable() export class CheckUserHavePermission implements CanActivate { constructor( private readonly deviceRepository: DeviceRepository, private readonly userRepository: UserRepository, ) {} async canActivate(context: ExecutionContext): Promise { const req = context.switchToHttp().getRequest(); try { const userUuid = req.user.uuid; const { deviceUuid } = req.params; const userIsFound = await this.checkUserIsFound(userUuid); if (!userIsFound) { throw new NotFoundException('User not found'); } const userDevicePermission = await this.checkUserDevicePermission( userUuid, deviceUuid, ); if ( userDevicePermission === PermissionType.READ || userDevicePermission === PermissionType.CONTROLLABLE ) { return true; } else { throw new BadRequestException('You do not have access to this device'); } } catch (error) { this.handleGuardError(error, context); return false; } } private async checkUserIsFound(userUuid: string) { const userData = await this.userRepository.findOne({ where: { uuid: userUuid }, }); return !!userData; } private async checkUserDevicePermission( userUuid: string, deviceUuid: string, ): Promise { const device = await this.deviceRepository.findOne({ where: { uuid: deviceUuid, permission: { userUuid: userUuid }, isActive: true, }, relations: ['permission', 'permission.permissionType'], }); if (!device) { throw new BadRequestException('You do not have access to this device'); } return device.permission[0].permissionType.type; // Assuming permissionType is a string } private handleGuardError(error: Error, context: ExecutionContext) { const response = context.switchToHttp().getResponse(); if (error instanceof NotFoundException) { response .status(HttpStatus.NOT_FOUND) .json({ statusCode: HttpStatus.NOT_FOUND, message: error.message }); } else if (error instanceof BadRequestException) { response.status(HttpStatus.BAD_REQUEST).json({ statusCode: HttpStatus.BAD_REQUEST, message: error.message, }); } else { response.status(HttpStatus.INTERNAL_SERVER_ERROR).json({ statusCode: HttpStatus.INTERNAL_SERVER_ERROR, message: error.message, }); } } }