import { OnModuleInit, Inject, Injectable, HttpException, HttpStatus, InternalServerErrorException, } from '@nestjs/common'; import { firstValueFrom, lastValueFrom } from 'rxjs'; import { Link } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/entities'; import { DucClient } from '../duc/client.config'; import { ClientGrpc } from '@nestjs/microservices'; import { ProtoServices } from '@dadosfera/protospack-v2/dist/lib/Duc'; import { CustomerUpdateRequest } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/messages'; import { CustomersProtoService } from '@dadosfera/protospack-v2/dist/lib/Duc/interfaces/write-service'; import ErrorCodes from 'src/utils/errorCodes'; import jwt from 'jsonwebtoken'; import { GetSecretValueCommand, SecretsManagerClient, } from '@aws-sdk/client-secrets-manager'; import getEnv from 'src/utils/getEnv'; import { logger } from 'elastic-apm-node'; import { ReadService, ProtoServices as PipelineProtoServices, } from '@dadosfera/protospack-v2/dist/lib/PipelineV2'; import { Metadata } from '@grpc/grpc-js'; import { PipelinesClientConfiguration } from '../pipelinesV2/pipelines-client'; import DadosferaLogger from '@dadosfera/dadosfera-logs'; // This function will accept any string, which may result in a bug. @Injectable() export class CustomersService implements OnModuleInit { private customerService: CustomersProtoService; private logger: DadosferaLogger; private pipelineReadService: ReadService.PipelineV2ReadService; constructor( @Inject(DucClient.name) private readonly grpcClient: ClientGrpc, @Inject(PipelinesClientConfiguration.name) private readonly pipelinesGrpcClient: ClientGrpc, @Inject(DadosferaLogger) dadosferaLogger: DadosferaLogger, ) { this.logger = dadosferaLogger.logger; } onModuleInit() { this.customerService = this.grpcClient.getService( ProtoServices.CustomersProtoService, ); this.pipelineReadService = this.pipelinesGrpcClient.getService( PipelineProtoServices.PipelineV2ReadService, ); } async getLinks(customerId: string) { try { const result = await lastValueFrom( this.customerService.CustomerFindOneById({ id: customerId }), ); return result.customer?.links || []; } catch (err) { if (err.details === ErrorCodes.CUSTOMER.NOT_FOUND) throw new HttpException(err.details, HttpStatus.NOT_FOUND); throw err; } } async setLinks(customerId: string, links: Link[]) { if (!customerId || !links) { throw new HttpException(null, HttpStatus.BAD_REQUEST); } try { return await firstValueFrom( this.customerService.CustomerUpdate({ id: customerId, links, } as CustomerUpdateRequest), ); } catch (err) { if (err.details === ErrorCodes.CUSTOMER.NOT_FOUND) throw new HttpException(err.details, HttpStatus.NOT_FOUND); else throw err; } } async generateToken( expiresIn = '30m', data: { customerId: string; userId: string; customerName: string }, ) { const { customerId, userId: generatedById, customerName } = data; const secretsManagerClient = new SecretsManagerClient({}); const getSecretComand = new GetSecretValueCommand({ SecretId: `${getEnv()}/${customerName}/jwt-signing-key`, }); let private_key_pem; await secretsManagerClient .send(getSecretComand) .then((res) => { const secret = JSON.parse(res.SecretString); private_key_pem = secret.private_key_pem; }) .catch((err) => { logger.error(err.stack); throw new InternalServerErrorException( 'Error finding keys for customer', ); }); let jwt_token; try { jwt_token = jwt.sign( { customerId, generatedById, }, private_key_pem, { algorithm: 'RS256', expiresIn, issuer: 'maestro', }, ); } catch (err) { logger.error(err.stack); throw new InternalServerErrorException('Error generating token'); } // const verify = jwt.verify(jwt_token, public_key_pem, { // algorithms: ['RS256'], // issuer: 'maestro', // }); // const decoded = jwt.decode(jwt_token, { complete: true }); return jwt_token; } async getMonitoringDashboardUrl(metadata: Metadata) { logger.info('CustomersService - getMonitoringDashboardUrl'); const res = await lastValueFrom( this.pipelineReadService.PipelineV2GetDashboardUrl( { dashboard_id: '98', exp: '15m', metabase_customer_name: 'dadosferatech', }, metadata, ), ); logger.info('Done'); return res; } async getLogsDashboardUrl(metadata: Metadata) { logger.info('CustomersService - getMixPanelLogsDashboardUrl'); const res = await lastValueFrom( this.pipelineReadService.PipelineV2GetDashboardUrl( { dashboard_id: '103', exp: '15m', metabase_customer_name: 'dadosferatech', }, metadata, ), ); logger.info('Done'); return res; } }