import { CanActivate, ExecutionContext, Injectable, HttpStatus, } from '@nestjs/common'; import { TuyaContext } from '@tuya/tuya-connector-nodejs'; import { BadRequestException, NotFoundException } from '@nestjs/common'; import { DeviceRepository } from '@app/common/modules/device/repositories'; import { ConfigService } from '@nestjs/config'; import { UserRepository } from '@app/common/modules/user/repositories'; @Injectable() export class CheckDeviceGuard implements CanActivate { private tuya: TuyaContext; constructor( private readonly configService: ConfigService, private readonly userRepository: UserRepository, private readonly deviceRepository: DeviceRepository, ) { const accessKey = this.configService.get('auth-config.ACCESS_KEY'); const secretKey = this.configService.get('auth-config.SECRET_KEY'); const tuyaEuUrl = this.configService.get('tuya-config.TUYA_EU_URL'); this.tuya = new TuyaContext({ baseUrl: tuyaEuUrl, accessKey, secretKey, }); } async canActivate(context: ExecutionContext): Promise { const req = context.switchToHttp().getRequest(); try { if (req.body && req.body.userUuid && req.body.deviceTuyaUuid) { const { userUuid, deviceTuyaUuid } = req.body; await this.checkUserIsFound(userUuid); await this.checkDeviceIsFoundFromTuya(deviceTuyaUuid); } else { throw new BadRequestException('Invalid request parameters'); } return true; } catch (error) { this.handleGuardError(error, context); return false; } } private async checkUserIsFound(userUuid: string) { const user = await this.userRepository.findOne({ where: { uuid: userUuid, }, }); if (!user) { throw new NotFoundException('User not found'); } } async checkDeviceIsFoundFromTuya(deviceTuyaUuid: string) { const path = `/v1.1/iot-03/devices/${deviceTuyaUuid}`; const response = await this.tuya.request({ method: 'GET', path, }); if (!response.success) { throw new NotFoundException('Device not found from Tuya'); } } 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.BAD_REQUEST).json({ statusCode: HttpStatus.BAD_REQUEST, message: error.message || 'Invalid UUID', }); } } }