Compare commits

...
10 changed files with 275 additions and 16316 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
<p align="center">
<image src="./assets/maestro.svg" style="width:10rem">
<h1 align="center">Maestro</h1>
<h1 align="center">Maestro</h1>
</p>
-16192
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -31,7 +31,7 @@
"@nestjs/platform-express": "^8.4.3",
"@nestjs/schedule": "^1.1.0",
"@nestjs/swagger": "^5.2.1",
"@victorradael/protospack": "^1.8.0",
"@victorradael/protospack": "^2.3.0",
"axios": "^0.25.0",
"dotenv": "^14.2.0",
"helmet": "^5.0.2",
+54 -85
View File
@@ -2,17 +2,18 @@ import { OnModuleInit, Inject } from '@nestjs/common';
import { ClientGrpc } from '@nestjs/microservices';
import {
AuthConfirmationRequest,
AuthDisableTotpMfaRequest,
AuthEnableTotpMfaRequest,
AuthResendConfirmationCodeRequest,
AuthServiceInterface,
AuthVerifyTotpMfaRequest,
DucServicesNames,
AuthServiceInterface,
AuthSignInRequest,
AuthRefreshAccessTokenRequest,
AuthConfirmationRequest,
AuthResendConfirmationCodeRequest,
AuthEnableTotpMfaRequest,
AuthDisableTotpMfaRequest,
AuthDismissTotpMfaRequest,
AuthVerifyTotpMfaRequest,
} from '@victorradael/protospack';
import { ISignIn, IRefreshAccessToken } from './interfaces';
export class AuthClientService implements OnModuleInit {
private authService: AuthServiceInterface;
constructor(
@@ -25,111 +26,89 @@ export class AuthClientService implements OnModuleInit {
);
}
async signIn({ username, password, totp }: ISignIn): Promise<any> {
async signIn({ username, password, totp }: AuthSignInRequest): Promise<any> {
console.log('AuthClientService', 'SignIn');
const tokens = await new Promise((resolve, reject) => {
return new Promise((resolve, reject) => {
this.authService.signIn({ username, password, totp }).subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
next: resolve,
//error: (err) => reject(err.details),
error: (err) => {
console.log(err);
reject(err.details);
},
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return tokens;
});
}
async enableTotpMFA({
username,
accessToken,
password,
}: AuthEnableTotpMfaRequest): Promise<any> {
console.log('AuthClientService', 'enableTotpMFA');
const tokens = await new Promise((resolve, reject) => {
this.authService.enableTotpMfa({ username, password }).subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
return new Promise((resolve, reject) => {
this.authService.enableTotpMfa({ accessToken, password }).subscribe({
next: resolve,
error: (err) => reject(err.details),
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return tokens;
});
}
async disableTotpMFA({
username,
accessToken,
password,
totp,
}: AuthDisableTotpMfaRequest): Promise<any> {
console.log('AuthClientService', 'disableTotpMFA');
const tokens = await new Promise((resolve, reject) => {
this.authService.disableTotpMfa({ username, password, totp }).subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
return new Promise((resolve, reject) => {
this.authService.disableTotpMfa({ accessToken, password }).subscribe({
next: resolve,
error: (err) => reject(err.details),
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
}
async dismissTotpMFA({
accessToken,
}: AuthDismissTotpMfaRequest): Promise<any> {
console.log('AuthClientService', 'dismissTotpMFA');
return new Promise((resolve, reject) => {
this.authService.dismissTotpMfa({ accessToken }).subscribe({
next: resolve,
error: (err) => reject(err.details),
complete() {
console.log('done');
},
});
return tokens;
});
}
async verifyTotp({
username,
accessToken,
totp,
}: AuthVerifyTotpMfaRequest): Promise<any> {
console.log('AuthClientService', 'disableTotpMFA');
const tokens = await new Promise((resolve, reject) => {
this.authService.verifyTotp({ username, accessToken, totp }).subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
return new Promise((resolve, reject) => {
this.authService.verifyTotp({ accessToken, totp }).subscribe({
next: resolve,
error: (err) => reject(err.details),
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return tokens;
});
}
async confirmRegister({
@@ -190,29 +169,19 @@ export class AuthClientService implements OnModuleInit {
async refreshAccessToken({
username,
refreshToken,
}: IRefreshAccessToken): Promise<any> {
}: AuthRefreshAccessTokenRequest): Promise<any> {
console.log('AuthClientService', 'RefreshAccessToken');
const tokens = await new Promise((resolve, reject) => {
return new Promise((resolve, reject) => {
this.authService
.refreshAccessToken({ username, refreshToken })
.subscribe({
next(x) {
resolve(x);
},
error(err) {
console.log('Observable Error');
reject(err);
},
next: resolve,
error: (err) => reject(err.details),
complete() {
console.log('done');
},
});
})
.then((res) => res)
.catch((err) => {
throw new Error(err);
});
return tokens;
});
}
}
-10
View File
@@ -1,10 +0,0 @@
export interface ISignIn {
username: string;
password: string;
totp: string;
}
export interface IRefreshAccessToken {
username: string;
refreshToken: string;
}
+70 -22
View File
@@ -3,15 +3,21 @@ import {
Controller,
Headers,
Post,
HttpCode,
HttpStatus,
UnauthorizedException,
} from '@nestjs/common';
import {
AuthSignInRequest,
AuthRefreshAccessTokenRequest,
AuthEnableTotpMfaRequest,
AuthDisableTotpMfaRequest,
AuthVerifyTotpMfaRequest,
} from '@victorradael/protospack';
import { AuthClientService } from 'src/clients/auth/client.service';
import { ISignIn, IRefreshAccessToken } from 'src/clients/auth/interfaces';
import ErrorBuilder from '../../utils/ErrorBuilder';
@Controller('auth')
export class AuthController {
@@ -19,82 +25,124 @@ export class AuthController {
// DEPRECADO!
@Post()
async signIn_old(@Body() body: ISignIn) {
@HttpCode(HttpStatus.OK)
async signIn_old(@Body() body: AuthSignInRequest) {
console.log(`/auth`, 'SignIn_old');
return this.signIn(body);
}
@Post('login')
async signIn_login(@Body() body: ISignIn) {
@HttpCode(HttpStatus.OK)
async signIn_login(@Body() body: AuthSignInRequest) {
console.log(`/auth`, 'SignIn_login');
return this.signIn(body);
}
@Post('sign-in')
async signIn(@Body() { username, password, totp }: ISignIn) {
@HttpCode(HttpStatus.OK)
async signIn(@Body() { username, password, totp }: AuthSignInRequest) {
console.log(`/auth`, 'SignIn');
const tokens = await this.authClient
.signIn({ username, password, totp })
.then((result) => result)
.catch((err) => {
throw new UnauthorizedException(err.message);
throw ErrorBuilder(err);
});
return tokens;
}
@Post('refresh-access-token')
@HttpCode(HttpStatus.OK)
async refreshAccessToken(
@Body() { username, refreshToken }: IRefreshAccessToken,
@Body() { username, refreshToken }: AuthRefreshAccessTokenRequest,
) {
console.log(`/auth`, 'RefreshAccessToken');
const accessToken = await this.authClient
.refreshAccessToken({ username, refreshToken })
.then((result) => result)
.catch((err) => {
throw new UnauthorizedException(err.message);
throw ErrorBuilder(err);
});
return accessToken;
}
@Post('enable-totp')
@HttpCode(HttpStatus.OK)
async enableTotpMFA(
@Body() { username, password }: AuthEnableTotpMfaRequest,
@Body() body: AuthEnableTotpMfaRequest,
@Headers() headers,
) {
console.log(`/auth`, 'enable-totp');
const enableTotpResponse = await this.authClient
.enableTotpMFA({ username, password })
.then((result) => result)
const { password } = body;
const { authorization: accessToken } = headers;
const response = await this.authClient
.enableTotpMFA({ accessToken, password })
.catch((err) => {
throw new UnauthorizedException(err.message);
throw ErrorBuilder(err);
});
return enableTotpResponse;
return response;
}
@Post('disable-totp')
@HttpCode(HttpStatus.OK)
async disableTotpMFA(
@Body() body: AuthDisableTotpMfaRequest,
@Headers() headers,
) {
console.log(`/auth`, 'disable-totp');
const { password } = body;
const { authorization: accessToken } = headers;
const response = await this.authClient
.disableTotpMFA({ accessToken, password })
.catch((err) => {
throw ErrorBuilder(err);
});
return response;
}
@Post('dismiss-totp')
@HttpCode(HttpStatus.OK)
async dismissTotpMFA(@Headers() headers) {
console.log(`/auth`, 'disable-totp');
const { authorization: accessToken } = headers;
const response = await this.authClient
.dismissTotpMFA({ accessToken })
.catch((err) => {
throw ErrorBuilder(err);
});
return response;
}
@Post('verify-totp')
@HttpCode(HttpStatus.OK)
async verifyTotp(
@Body() body: AuthVerifyTotpMfaRequest,
@Headers() headers,
): Promise<any> {
console.log(`/auth`, 'enable-totp');
const { username, totp } = body;
const { Authorization } = headers;
const { totp } = body;
const { authorization: accessToken } = headers;
const enableTotpResponse = await this.authClient
.verifyTotp({ username, totp, accessToken: Authorization })
.then((result) => result)
const response = await this.authClient
.verifyTotp({ accessToken, totp })
.catch((err) => {
throw new UnauthorizedException(err.message);
throw ErrorBuilder(err);
});
return enableTotpResponse;
return response;
}
}
+22 -4
View File
@@ -7,13 +7,20 @@ import { objectCamelToSnake } from 'src/utils/CaseConverter';
export class PipelinesService {
constructor(private pipelineClient: PipelinesClientService) {}
adjustPayload(payload) {
payload.input = payload.input.input_s3 || payload.input.input_jdbc;
}
async create(createPipelineDto) {
try {
const createPipelineResponse = await this.pipelineClient.create(
createPipelineDto,
);
return objectCamelToSnake(createPipelineResponse);
const pipeline = objectCamelToSnake(createPipelineResponse);
this.adjustPayload(pipeline);
return pipeline;
} catch (err) {
console.log(err);
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
@@ -23,7 +30,11 @@ export class PipelinesService {
async findOne(data: IIdRequest) {
try {
const findOnePipelineResponse = await this.pipelineClient.findOne(data);
return objectCamelToSnake(findOnePipelineResponse);
const pipeline = objectCamelToSnake(findOnePipelineResponse);
this.adjustPayload(pipeline);
return pipeline;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
@@ -33,7 +44,11 @@ export class PipelinesService {
try {
const findAllPipelineResponse = await this.pipelineClient.findAll(data);
return objectCamelToSnake(findAllPipelineResponse);
const pipelines = objectCamelToSnake(findAllPipelineResponse);
pipelines.forEach((pipeline) => {
this.adjustPayload(pipeline);
});
return pipelines;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
@@ -47,7 +62,10 @@ export class PipelinesService {
...data,
});
return objectCamelToSnake(updatePipelineResponse);
const pipeline = objectCamelToSnake(updatePipelineResponse);
this.adjustPayload(pipeline);
return pipeline;
} catch (err) {
throw new HttpException(err.message, HttpStatus.NOT_FOUND);
}
+106
View File
@@ -0,0 +1,106 @@
import { HttpStatus, HttpException } from '@nestjs/common';
import ErrorCodes from './errorCodes';
function Builder({ statusCode, message, error, code }) {
return new HttpException({ statusCode, message, error, code }, statusCode);
}
export default function ErrorBuilder(code: string) {
console.log(code);
switch (code) {
case ErrorCodes.AUTH.WRONG_CREDENTIALS:
return Builder({
statusCode: HttpStatus.UNAUTHORIZED,
error: 'Não autenticado',
message: 'Usuário ou senha incorretos',
code,
});
case ErrorCodes.AUTH.WRONG_PASSWORD_CONFIRMATION:
return Builder({
statusCode: HttpStatus.UNAUTHORIZED,
error: 'Senha incorreta',
message: 'Confirmação de senha incorreta',
code,
});
case ErrorCodes.AUTH.TOTP_NOT_ENABLED:
return Builder({
statusCode: HttpStatus.PRECONDITION_FAILED,
error: 'Não permitido',
message: 'A autenticação multifator não está habilitada',
code,
});
case ErrorCodes.AUTH.TOTP_ALREADY_ENABLED:
return Builder({
statusCode: HttpStatus.PRECONDITION_FAILED,
error: 'Não permitido',
message: 'A autenticação multifator já está habilitada',
code,
});
case ErrorCodes.AUTH.TOTP_ALREADY_DISABLED:
return Builder({
statusCode: HttpStatus.PRECONDITION_FAILED,
error: 'Não permitido',
message: 'A autenticação multifator já está desabilitada',
code,
});
case ErrorCodes.AUTH.TOTP_REQUIRED:
return Builder({
statusCode: HttpStatus.UNAUTHORIZED,
error: 'Não autenticado',
message: 'Informe o token de autenticação multifator',
code,
});
case ErrorCodes.AUTH.CODE_MISMATCH:
case ErrorCodes.AUTH.CODE_ALREADY_USED:
return Builder({
statusCode: HttpStatus.UNAUTHORIZED,
error: 'Não autenticado',
message: 'Token de autenticação multifator inválido',
code,
});
case ErrorCodes.RATE_LIMIT:
return Builder({
statusCode: HttpStatus.TOO_MANY_REQUESTS,
error: 'Limite excedido',
message:
'Você tentou realizar essa operação muitas vezes. Tente novamente mais tarde',
code,
});
case ErrorCodes.AUTH.UNAUTHORIZED:
return Builder({
statusCode: HttpStatus.UNAUTHORIZED,
error: 'Não autenticado',
message: 'É necessário estar logado para realizar essa operação',
code,
});
case ErrorCodes.AUTH.FORBIDDEN:
return Builder({
statusCode: HttpStatus.FORBIDDEN,
error: 'Não autorizado',
message:
'Você não tem permissões suficientes para realizar essa operação',
code,
});
case ErrorCodes.UNKNOWN:
default:
return Builder({
statusCode: HttpStatus.INTERNAL_SERVER_ERROR,
error: 'Desconhecido',
message:
'Erro desconhecido. Tente novamente ou entre em contato com o suporte',
code: ErrorCodes.UNKNOWN,
});
}
}
+20
View File
@@ -0,0 +1,20 @@
export const Auth = {
UNAUTHORIZED: 'AUTH.UNAUTHORIZED',
FORBIDDEN: 'AUTH.FORBIDDEN',
WRONG_CREDENTIALS: 'AUTH.WRONG_CREDENTIALS',
WRONG_PASSWORD_CONFIRMATION: 'AUTH.WRONG_PASSWORD_CONFIRMATION',
TOTP_NOT_ENABLED: 'AUTH.TOTP_NOT_ENABLED',
TOTP_ALREADY_ENABLED: 'AUTH.TOTP_ALREADY_ENABLED',
TOTP_ALREADY_DISABLED: 'AUTH.TOTP_ALREADY_DISABLED',
TOTP_REQUIRED: 'AUTH.TOTP_REQUIRED',
CODE_MISMATCH: 'AUTH.CODE_MISMATCH',
CODE_ALREADY_USED: 'AUTH.CODE_ALREADY_USED',
};
const ErrorCodes = {
UNKNOWN: 'UNKNOWN',
RATE_LIMIT: 'RATE_LIMIT',
AUTH: Auth,
};
export default ErrorCodes;
+1 -1
View File
File diff suppressed because one or more lines are too long