diff --git a/src/api/controllers/instance.controller.ts b/src/api/controllers/instance.controller.ts index 0ffa885d..0d743f37 100644 --- a/src/api/controllers/instance.controller.ts +++ b/src/api/controllers/instance.controller.ts @@ -3,9 +3,9 @@ import { isURL } from 'class-validator'; import EventEmitter2 from 'eventemitter2'; import { v4 } from 'uuid'; -import { ConfigService, HttpServer, WaBusiness } from '../../config/env.config'; +import { Auth, ConfigService, HttpServer, WaBusiness } from '../../config/env.config'; import { Logger } from '../../config/logger.config'; -import { BadRequestException, InternalServerErrorException } from '../../exceptions'; +import { BadRequestException, InternalServerErrorException, UnauthorizedException } from '../../exceptions'; import { InstanceDto, SetPresenceDto } from '../dto/instance.dto'; import { ChatwootService } from '../integrations/chatwoot/services/chatwoot.service'; import { RabbitmqService } from '../integrations/rabbitmq/services/rabbitmq.service'; @@ -679,11 +679,27 @@ export class InstanceController { }; } - public async fetchInstances({ instanceName, instanceId, number }: InstanceDto) { - if (instanceName) { - this.logger.verbose('requested fetchInstances from ' + instanceName + ' instance'); - this.logger.verbose('instanceName: ' + instanceName); - return this.waMonitor.instanceInfo(instanceName); + public async fetchInstances({ instanceName, instanceId, number }: InstanceDto, key: string) { + const env = this.configService.get('AUTHENTICATION').API_KEY; + + let name = instanceName; + let arrayReturn = false; + + if (env.KEY !== key) { + const instanceByKey = await this.repository.auth.findByKey(key); + console.log('instanceByKey', instanceByKey); + if (instanceByKey) { + name = instanceByKey._id; + arrayReturn = true; + } else { + throw new UnauthorizedException(); + } + } + + if (name) { + this.logger.verbose('requested fetchInstances from ' + name + ' instance'); + this.logger.verbose('instanceName: ' + name); + return this.waMonitor.instanceInfo(name, arrayReturn); } else if (instanceId || number) { return this.waMonitor.instanceInfoById(instanceId, number); } diff --git a/src/api/guards/auth.guard.ts b/src/api/guards/auth.guard.ts index ccc73a58..b7c7c7c0 100644 --- a/src/api/guards/auth.guard.ts +++ b/src/api/guards/auth.guard.ts @@ -59,6 +59,10 @@ async function apikey(req: Request, _: Response, next: NextFunction) { const env = configService.get('AUTHENTICATION').API_KEY; const key = req.get('apikey'); + if (!key) { + throw new UnauthorizedException(); + } + if (env.KEY === key) { return next(); } @@ -66,12 +70,19 @@ async function apikey(req: Request, _: Response, next: NextFunction) { if ((req.originalUrl.includes('/instance/create') || req.originalUrl.includes('/instance/fetchInstances')) && !key) { throw new ForbiddenException('Missing global api key', 'The global api key must be set'); } + const param = req.params as unknown as InstanceDto; try { - const param = req.params as unknown as InstanceDto; - const instanceKey = await repository.auth.find(param.instanceName); - if (instanceKey.apikey === key) { - return next(); + if (param?.instanceName) { + const instanceKey = await repository.auth.find(param.instanceName); + if (instanceKey?.apikey === key) { + return next(); + } + } else { + const instanceByKey = await repository.auth.findByKey(key); + if (instanceByKey) { + return next(); + } } } catch (error) { logger.error(error); diff --git a/src/api/repository/auth.repository.ts b/src/api/repository/auth.repository.ts index 1e4bbb81..6a296902 100644 --- a/src/api/repository/auth.repository.ts +++ b/src/api/repository/auth.repository.ts @@ -68,6 +68,20 @@ export class AuthRepository extends Repository { } } + public async findByKey(key: string): Promise { + try { + this.logger.verbose('finding auth'); + if (this.dbSettings.ENABLED) { + this.logger.verbose('finding auth in db'); + return await this.authModel.findOne({ apikey: key }); + } + + return {}; + } catch (error) { + return {}; + } + } + public async list(): Promise { try { if (this.dbSettings.ENABLED) { diff --git a/src/api/routes/instance.router.ts b/src/api/routes/instance.router.ts index a56271a4..d2cc6fb8 100644 --- a/src/api/routes/instance.router.ts +++ b/src/api/routes/instance.router.ts @@ -103,13 +103,15 @@ export class InstanceRouter extends RouterBroker { logger.verbose('request body: '); logger.verbose(req.body); + const key = req.get('apikey'); + logger.verbose('request query: '); logger.verbose(req.query); const response = await this.dataValidate({ request: req, schema: null, ClassRef: InstanceDto, - execute: (instance) => instanceController.fetchInstances(instance), + execute: (instance) => instanceController.fetchInstances(instance, key), }); return res.status(HttpStatus.OK).json(response); diff --git a/src/api/services/monitor.service.ts b/src/api/services/monitor.service.ts index afeffa95..af93fa74 100644 --- a/src/api/services/monitor.service.ts +++ b/src/api/services/monitor.service.ts @@ -83,7 +83,7 @@ export class WAMonitoringService { } } - public async instanceInfo(instanceName?: string) { + public async instanceInfo(instanceName?: string, arrayReturn = false) { this.logger.verbose('get instance info'); if (instanceName && !this.waInstances[instanceName]) { throw new NotFoundException(`Instance "${instanceName}" not found`); @@ -171,6 +171,9 @@ export class WAMonitoringService { this.logger.verbose('return instance info: ' + instances.length); + if (arrayReturn) { + return [instances.find((i) => i.instance.instanceName === instanceName) ?? instances]; + } return instances.find((i) => i.instance.instanceName === instanceName) ?? instances; }