Compare commits

...
11 Commits
Author SHA1 Message Date
arthur simas a0089b5d5d Merge pull request #121 from dadosfera/fix/terms-of-use-ip
FIX: terms of use ip:port
2022-07-15 11:15:12 -03:00
Arthur Simas 1eb76d4b1c FIX: terms of use ip:port 2022-07-15 11:08:46 -03:00
arthur simas a206aad8db Merge pull request #120 from dadosfera/feature/terms-of-use
FEAT: terms of use
2022-07-14 14:50:01 -03:00
Arthur Simas f383cf49d5 FIX: added get token method 2022-07-11 02:13:53 -03:00
Arthur Simas db78ee3d8b FEAT: terms of use 2022-07-11 02:13:33 -03:00
arthur simas cc3b34d87e Merge pull request #119 from dadosfera/fix/error-handling
FIX: added exception filter to catch unhandled errors
2022-07-07 20:28:44 -03:00
Arthur Simas 88bc7fe625 FIX: added exception filter to catch unhandled errors 2022-07-07 20:24:27 -03:00
Gabriel Amorim 137f129e13 Merge pull request #118 from dadosfera/conditional-apm-import
FIX: Conditional apm import
2022-07-07 20:22:55 -03:00
Gabriel Rosa f49c5ac1c1 FIX: conditionally importing apm 2022-07-07 20:04:42 -03:00
Gabriel Rosa d288a4f357 FIX: conditionally importing apm 2022-07-07 18:18:53 -03:00
Gabriel Rosa 9f009309cb FIX: conditionally importing apm 2022-07-07 17:51:28 -03:00
11 changed files with 180 additions and 14 deletions
+7 -7
View File
@@ -36,7 +36,7 @@
"passport-hubspot-oauth2": "^1.0.3",
"passport-mailchimp": "^1.1.0",
"protospack": "2.5.1",
"protospack-v2": "3.0.0",
"protospack-v2": "3.1.1",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.5.5",
@@ -8997,9 +8997,9 @@
}
},
"node_modules/protospack-v2": {
"version": "3.0.0",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/protospack-v2/-/protospack-v2-3.0.0.tgz",
"integrity": "sha512-GEFbf8+vVaq/lA28K4nFf7bOSlghQJn/aeVnrYzh4YJUaa1+ccNz3uQs9p5OGbfjt2u/fFE5rHGEBUtueAA8KA==",
"version": "3.1.1",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/protospack-v2/-/protospack-v2-3.1.1.tgz",
"integrity": "sha512-uY9hsP2oO7kar1EUUjUhVLI8VQ3seWO2+WVS0XS9vjWZPUI82k7KqB70uYB+5ws2dMSowomPjiqpQ13VNjk6ZQ==",
"dependencies": {
"rxjs": "^7.5.5",
"ts-proto": "^1.112.2"
@@ -17198,9 +17198,9 @@
}
},
"protospack-v2": {
"version": "3.0.0",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/protospack-v2/-/protospack-v2-3.0.0.tgz",
"integrity": "sha512-GEFbf8+vVaq/lA28K4nFf7bOSlghQJn/aeVnrYzh4YJUaa1+ccNz3uQs9p5OGbfjt2u/fFE5rHGEBUtueAA8KA==",
"version": "3.1.1",
"resolved": "https://dadosfera-611330257153.d.codeartifact.us-east-1.amazonaws.com:443/npm/dadosfera-npm/protospack-v2/-/protospack-v2-3.1.1.tgz",
"integrity": "sha512-uY9hsP2oO7kar1EUUjUhVLI8VQ3seWO2+WVS0XS9vjWZPUI82k7KqB70uYB+5ws2dMSowomPjiqpQ13VNjk6ZQ==",
"requires": {
"rxjs": "^7.5.5",
"ts-proto": "^1.112.2"
+1 -1
View File
@@ -51,7 +51,7 @@
"passport-hubspot-oauth2": "^1.0.3",
"passport-mailchimp": "^1.1.0",
"protospack": "2.5.1",
"protospack-v2": "3.0.0",
"protospack-v2": "3.1.1",
"reflect-metadata": "^0.1.13",
"rimraf": "^3.0.2",
"rxjs": "^7.5.5",
+2
View File
@@ -40,6 +40,7 @@ import { SalesforceStrategy } from './modules/oauth/passport-strategies/salesfor
import { ConnectorClientConfiguration } from './clients/connector/client.config';
import { ConnectorController } from './modules/connector/connector.controller';
import { ConnectorClientService } from './clients/connector/client.service';
import { TermsOfUseModule } from './modules/termsOfUse/termsOfUse.module';
const inputClient = new InputsClientConfiguration();
const outputClient = new OutputsClientConfiguration();
@@ -88,6 +89,7 @@ const connectorClient = new ConnectorClientConfiguration();
}),
AuthModule,
PermissionsModule,
TermsOfUseModule,
ClientsModule.register([
{
@@ -0,0 +1,22 @@
import { ExceptionFilter, Catch, ArgumentsHost } from '@nestjs/common';
import { Response } from 'express';
import ErrorBuilder from '../utils/ErrorBuilder';
@Catch(Error)
export class GrpcToHttpExceptionFilter implements ExceptionFilter {
catch(exception: any, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
// return this exception directly if is already of type ErrorBuilder,
// else transform it using the ErrorBuilder
const err =
exception.constructor.name === ErrorBuilder.name
? exception
: new ErrorBuilder(exception.details);
const { statusCode } = err.response;
return response.status(statusCode).json(err.response);
}
}
+1 -4
View File
@@ -1,20 +1,17 @@
import 'elastic-apm-node/start';
if (process.env.ENV !== 'local') require('elastic-apm-node/start');
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { writeFileSync } from 'fs';
import helmet from 'helmet';
import { DadosferaLogger } from 'dadosfera-logs';
import documentEmpty from '../swagger_empty.json';
import { AppModule } from './app.module';
async function bootstrap() {
DadosferaLogger.setupLogger({
serviceName: 'maestro',
serviceEnvironment: process.env.ENV,
});
const logger = new DadosferaLogger().logger;
const orginalWinstonLog = logger.log.bind(logger);
+3
View File
@@ -6,6 +6,7 @@ import {
HttpCode,
HttpStatus,
Inject,
UseFilters,
} from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import {
@@ -22,8 +23,10 @@ import {
import { AuthClientService } from './auth.service';
import { DadosferaLogger } from 'dadosfera-logs';
import { GrpcToHttpExceptionFilter } from '../../error/grpc-to-http-exception.filter';
@ApiTags('Auth')
@UseFilters(new GrpcToHttpExceptionFilter())
@Controller('auth')
export class AuthController {
logger: any;
@@ -0,0 +1,56 @@
import {
Body,
Controller,
Post,
Get,
HttpCode,
HttpStatus,
Inject,
Headers,
UseFilters,
} from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { TermsOfUseAcceptRequest } from 'protospack-v2/dist/lib/Duc/interfaces/messages';
import { TermsOfUseClientService } from './termsOfUse.service';
import { DadosferaLogger } from 'dadosfera-logs';
import { GrpcToHttpExceptionFilter } from '../../error/grpc-to-http-exception.filter';
import { RequestUser, User } from '../../authentication/user.decorator';
@ApiTags('TermsOfUse')
@UseFilters(new GrpcToHttpExceptionFilter())
@Controller('terms-of-use')
export class TermsOfUseController {
logger: any;
constructor(
@Inject(DadosferaLogger)
dadosferaLogger: DadosferaLogger,
private termsOfUseClient: TermsOfUseClientService,
) {
this.logger = dadosferaLogger.logger;
}
@Get('token')
async getToken(@User({ required: true }) user: RequestUser) {
this.logger.info('/terms-of-use - get token');
return this.termsOfUseClient.getToken({ userId: user.user_id });
}
@Post('accept')
@HttpCode(HttpStatus.OK)
async accept(@Body() body: TermsOfUseAcceptRequest, @Headers() headers) {
this.logger.info('/terms-of-use - accept');
const { token } = body;
const fingerprint = {
ip: process.env.ENV !== 'local' ? headers['x-forwarded-for'] : '0.0.0.0',
port: process.env.ENV !== 'local' ? headers['x-forwarded-port'] : '00000',
userAgent: headers['user-agent'],
};
return this.termsOfUseClient.accept({ token, fingerprint });
}
}
@@ -0,0 +1,24 @@
import { Module } from '@nestjs/common';
import { ClientsModule } from '@nestjs/microservices';
import { DadosferaLogger } from 'dadosfera-logs';
import { TermsOfUseController } from './termsOfUse.controller';
import { TermsOfUseClientService } from './termsOfUse.service';
import { DucClient } from '../../clients/duc/client.config';
const ducClient = new DucClient();
@Module({
imports: [
ClientsModule.register([
{
name: 'DUC_PACKAGE',
...ducClient.config(),
},
]),
],
controllers: [TermsOfUseController],
providers: [TermsOfUseClientService, DadosferaLogger],
exports: [TermsOfUseClientService],
})
export class TermsOfUseModule {}
@@ -0,0 +1,40 @@
import { OnModuleInit, Inject, Injectable } from '@nestjs/common';
import { ClientGrpc } from '@nestjs/microservices';
import { DadosferaLogger } from 'dadosfera-logs';
import { lastValueFrom } from 'rxjs';
import { ProtoServices } from 'protospack-v2/dist/lib/Duc';
import { TermsOfUseProtoService as TermsOfUseServiceInterface } from 'protospack-v2/dist/lib/Duc/interfaces/write-service';
import {
TermsOfUseGetTokenRequest,
TermsOfUseAcceptRequest,
} from 'protospack-v2/dist/lib/Duc/interfaces/messages';
@Injectable()
export class TermsOfUseClientService implements OnModuleInit {
logger: any;
private termsOfUseService: TermsOfUseServiceInterface;
constructor(
@Inject(DadosferaLogger)
dadosferaLogger: DadosferaLogger,
@Inject('DUC_PACKAGE') private readonly grpcClient: ClientGrpc,
) {
this.logger = dadosferaLogger.logger;
}
onModuleInit() {
this.termsOfUseService =
this.grpcClient.getService<TermsOfUseServiceInterface>(
ProtoServices.TermsOfUseProtoService,
);
}
async getToken(data: TermsOfUseGetTokenRequest) {
return lastValueFrom(this.termsOfUseService.TermsOfUseGetToken(data));
}
async accept(data: TermsOfUseAcceptRequest) {
return lastValueFrom(this.termsOfUseService.TermsOfUseAccept(data));
}
}
+18 -2
View File
@@ -3,7 +3,7 @@ import { RpcException } from '@nestjs/microservices';
import ErrorCodes from './errorCodes';
function enrichErrorCode(code: string) {
export function EnrichErrorCode(code: string) {
switch (code) {
case ErrorCodes.AUTH.WRONG_CREDENTIALS:
return {
@@ -86,6 +86,22 @@ function enrichErrorCode(code: string) {
code,
};
case ErrorCodes.TERMS_OF_USE.UP_TO_DATE:
return {
statusCode: HttpStatus.FORBIDDEN,
error: 'Não autorizado',
message: 'Você já assinou os termos de uso',
code,
};
case ErrorCodes.TERMS_OF_USE.REQUIRED:
return {
statusCode: HttpStatus.FORBIDDEN,
error: 'Não autorizado',
message: 'É necessário aceitar os termos de uso para prosseguir',
code,
};
case ErrorCodes.RATE_LIMIT:
return {
statusCode: HttpStatus.TOO_MANY_REQUESTS,
@@ -138,7 +154,7 @@ export default class ErrorBuilder extends HttpException {
logger.log(code);
}
const { statusCode, message, error, code: rCode } = enrichErrorCode(code);
const { statusCode, message, error, code: rCode } = EnrichErrorCode(code);
super({ statusCode, message, error, code: rCode }, statusCode);
this.code = code;
}
+6
View File
@@ -14,11 +14,17 @@ export const AUTH = {
WEAK_NEW_PASSWORD: 'AUTH.WEAK_NEW_PASSWORD',
};
const TERMS_OF_USE = {
UP_TO_DATE: 'TERMS_OF_USE.UP_TO_DATE',
REQUIRED: 'TERMS_OF_USE.REQUIRED',
};
const ErrorCodes = {
UNKNOWN: 'UNKNOWN',
RATE_LIMIT: 'RATE_LIMIT',
INTERNAL: 'INTERNAL',
AUTH,
TERMS_OF_USE,
};
export default ErrorCodes;