diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4d89bc6..6d51f77 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -40,7 +40,7 @@ jobs: docker-compose -f build.docker-compose.yml run -e NPM_TOKEN=${NPM_TOKEN} --rm --entrypoint="npm run test" maestro - name: Remove Docker's Trash - continue-on-error: true + if: always() run: | - docker system prune - docker rmi -f $(docker images -aq) + docker system prune --volumes -a -f + docker system df diff --git a/src/app.module.ts b/src/app.module.ts index 8784fe0..361f1be 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -33,6 +33,7 @@ import { CatalogController } from './modules/catalog/catalog.controller'; import { CatalogService } from './modules/catalog/catalog.service'; import { HubspotStrategy } from './modules/oauth/passport-strategies/hubspot'; import { OauthController } from './modules/oauth/oauth.controller'; +import { getOauthSecrets } from './utils/OauthSecrets'; const authClient = new AuthClient(); const inputClient = new InputsClientConfiguration(); @@ -52,6 +53,7 @@ const transformationClient = new TransformationsClientConfiguration(); OauthController, ], providers: [ + { provide: 'OAUTH_SECRETS', useValue: getOauthSecrets() }, InputsService, TransformationsService, OutputsService, diff --git a/src/clients/inputs/client.service.ts b/src/clients/inputs/client.service.ts index 94bc176..7082ccd 100644 --- a/src/clients/inputs/client.service.ts +++ b/src/clients/inputs/client.service.ts @@ -3,6 +3,8 @@ import { Inject, HttpException, HttpStatus, + NotFoundException, + InternalServerErrorException, } from '@nestjs/common'; import { ClientGrpc } from '@nestjs/microservices'; import { @@ -22,23 +24,20 @@ import { objectSnakeToCamel, } from 'src/utils/CaseConverter'; import { mustache } from 'src/utils/mustache'; -import { OauthScrets } from 'src/utils/OauthSecrets'; +import { OauthSecrets } from 'src/utils/OauthSecrets'; import { URLSearchParams } from 'url'; import { IIdRequest, UpdateInputRequest } from './interfaces'; export class InputsClientService implements OnModuleInit { private inputService: InputService; - oauthSecrets: OauthScrets; constructor( @Inject('INPUTS_PACKAGE') private readonly grpcClient: ClientGrpc, + @Inject('OAUTH_SECRETS') private readonly oauthSecrets: OauthSecrets, ) {} async onModuleInit() { this.inputService = this.grpcClient.getService('InputService'); - this.oauthSecrets = new OauthScrets(); - await this.oauthSecrets.init(); - console.log(this.oauthSecrets); } async newCreate(createInputDto: InputNewCreateRequest) { @@ -54,7 +53,7 @@ export class InputsClientService implements OnModuleInit { async createGeneric(createInputGeneric) { console.log('InputClientService', 'Create'); const { info, ...data } = createInputGeneric; - data.credentials = await this.getInputTokens(data); + // data.credentials = await this.getInputTokens(data); if (data.options) delete data.options; if (data.credentials.oauth_code) delete data.credentials.oauth_code; const grpcPayload = { @@ -65,7 +64,12 @@ export class InputsClientService implements OnModuleInit { const structReturn = await lastValueFrom( this.inputService.Create(grpcPayload), - ); + ).catch((err) => { + if (err.details === 'Item Not found!') { + throw new NotFoundException('Input not found'); + } + throw new InternalServerErrorException(err.details); + }); objectCamelToSnake(structReturn); const inputCreated = DecodeGrpcStruct(structReturn.input); return { input: inputCreated }; diff --git a/src/main.ts b/src/main.ts index 4911612..fec1592 100644 --- a/src/main.ts +++ b/src/main.ts @@ -26,7 +26,8 @@ async function bootstrap() { const document = SwaggerModule.createDocument(app, config); writeFileSync('./swagger.json', JSON.stringify(document)); - SwaggerModule.setup('api', app, document); + if (process.env.ENV != 'stg' && process.env.ENV != 'prd') + SwaggerModule.setup('api', app, document); await app.listen(3333); } diff --git a/src/modules/inputs/dtos/input.model.ts b/src/modules/inputs/dtos/input.model.ts index 1a70e71..85b32a1 100644 --- a/src/modules/inputs/dtos/input.model.ts +++ b/src/modules/inputs/dtos/input.model.ts @@ -170,6 +170,8 @@ export class TestConnectionRes { database_tables: string[]; } export class CreateInputReq { + @ApiPropertyOptional() + id: string; @ApiProperty() plugin: string; @ApiProperty() diff --git a/src/modules/inputs/inputs.controller.ts b/src/modules/inputs/inputs.controller.ts index 6ddf90a..71f4340 100644 --- a/src/modules/inputs/inputs.controller.ts +++ b/src/modules/inputs/inputs.controller.ts @@ -46,8 +46,7 @@ export class InputsController { async testConnection(@Body() data: TestConnectionReq) { console.log(`/test-connection`, 'ON TEST CONNECTION ROUTE'); - const inputService = new InputsService(this.inputsClientService); - const response = await inputService.testConnection(data); + const response = await this.inputService.testConnection(data); return response; } @@ -60,8 +59,7 @@ export class InputsController { 'ON TEST CONNECTION GET COLUMNS ROUTE', ); - const inputService = new InputsService(this.inputsClientService); - const response = await inputService.getColumns(data); + const response = await this.inputService.getColumns(data); return response; } @@ -71,8 +69,18 @@ export class InputsController { async create(@Body() createInputDto: CreateInputReq) { console.log(`/input`, 'ON CREATE ROUTE'); - const inputService = new InputsService(this.inputsClientService); - const response = await inputService.create(createInputDto); + const response = await this.inputService.create(createInputDto); + + return response; + } + + @Post(':id') + @ApiOkResponse({ type: Input }) + async reCreate(@Param('id') id: string, @Body() input: CreateInputReq) { + if (!input.id) input.id = id; + console.log(`POST /${input.id}`, 'ON RECREATE ROUTE'); + + const response = await this.inputService.reCreate(input); return response; } @@ -81,9 +89,7 @@ export class InputsController { async findAll(@Body() body) { console.log(`/input`, 'ON FIND ALL ROUTE'); - const inputService = new InputsService(this.inputsClientService); - - const response = await inputService.findAll(body); + const response = await this.inputService.findAll(body); return response; } @@ -92,9 +98,8 @@ export class InputsController { async findOne(@Body() body, @Param() params) { const { id } = params; console.log(`/input/${id}`, 'ON FIND ONE ROUTE'); - const inputService = new InputsService(this.inputsClientService); - const response = await inputService.findOne({ id, ...body }); + const response = await this.inputService.findOne({ id, ...body }); return response; } @@ -106,9 +111,8 @@ export class InputsController { delete updateInputDto.info; console.log(`/input/${id}`, 'ON UPDATE ROUTE'); - const inputService = new InputsService(this.inputsClientService); - const response = await inputService.update(id, updateInputDto, info); + const response = await this.inputService.update(id, updateInputDto, info); return response; } @@ -119,9 +123,7 @@ export class InputsController { console.log(`/input/${id}`, 'ON DELETE ROUTE'); - const inputService = new InputsService(this.inputsClientService); - - const response = await inputService.remove({ id, ...data }); + const response = await this.inputService.remove({ id, ...data }); return response; } diff --git a/src/modules/inputs/inputs.service.ts b/src/modules/inputs/inputs.service.ts index 2d41455..a7c3715 100644 --- a/src/modules/inputs/inputs.service.ts +++ b/src/modules/inputs/inputs.service.ts @@ -75,6 +75,13 @@ export class InputsService { const adjustedInput = this.adjustInputPayload(response.input); return { ...response, input: adjustedInput }; } + async reCreate(data) { + const { info, cron } = data; + if (cron) this.validateCron({ info, cron }); + const response = await this.inputClient.createGeneric(data); + const adjustedInput = this.adjustInputPayload(response.input); + return { ...response, input: adjustedInput }; + } async getAvailableEntities(data): Promise<{ entities: string[] }> { return await this.inputClient.getAvailableEntities(data); } diff --git a/src/modules/oauth/oauth.controller.ts b/src/modules/oauth/oauth.controller.ts index b3b2c75..2b31ff2 100644 --- a/src/modules/oauth/oauth.controller.ts +++ b/src/modules/oauth/oauth.controller.ts @@ -1,20 +1,54 @@ -import { Controller, Get, Req, UseGuards } from '@nestjs/common'; +import { + BadRequestException, + Controller, + Get, + Query, + Redirect, + Req, + UseGuards, +} from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { AuthGuard } from '@nestjs/passport'; +import { InputsClientService } from 'src/clients/inputs/client.service'; +import { InputsService } from '../inputs/inputs.service'; @ApiTags('oauth') @Controller('oauth') export class OauthController { + inputService: InputsService; + frontendRedirectUri = ''; + constructor(private inputsClientService: InputsClientService) { + this.inputService = new InputsService(this.inputsClientService); + switch (process.env.ENV) { + case 'dev': + case 'stg': + this.frontendRedirectUri = `https://app.${process.env.ENV}.dadosfera.ai/auth-callback`; + break; + case 'prd': + this.frontendRedirectUri = `https://app.dadosfera.ai/auth-callback`; + break; + default: + this.frontendRedirectUri = `http://localhost:4200/coletix/auth-callback`; + } + } @UseGuards(AuthGuard('hubspot')) @Get('hubspot') async oauthHubspot(@Req() req) { - console.log(req); return true; } @UseGuards(AuthGuard('hubspot')) @Get('hubspot/callback') - async oauthHubspotCallback() { - console.log('hubspot/callback'); + @Redirect() + async oauthHubspotCallback(@Req() req, @Query('state') customer_id) { + const { authInfo } = req; + if (!authInfo) throw new BadRequestException('Oauth tokens not found'); + const { accessToken, refreshToken } = authInfo; + const response = await this.inputService.create({ + info: { customer_id, customer: 'customer', user_id: 'empty' }, + plugin: 'hubspot', + credentials: { access_token: accessToken, refresh_token: refreshToken }, + }); + return { url: `${this.frontendRedirectUri}?input_id=${response.input.id}` }; } } diff --git a/src/modules/oauth/passport-strategies/hubspot.ts b/src/modules/oauth/passport-strategies/hubspot.ts index 34f6096..2e33567 100644 --- a/src/modules/oauth/passport-strategies/hubspot.ts +++ b/src/modules/oauth/passport-strategies/hubspot.ts @@ -1,16 +1,20 @@ import { Strategy } from 'passport-hubspot-oauth2'; import { PassportStrategy } from '@nestjs/passport'; -import { Injectable } from '@nestjs/common'; +import { Inject, Injectable } from '@nestjs/common'; +import { OauthSecrets } from 'src/utils/OauthSecrets'; @Injectable() export class HubspotStrategy extends PassportStrategy(Strategy) { - constructor() { + constructor( + @Inject('OAUTH_SECRETS') + private readonly oauthSecrets: OauthSecrets, + ) { super( { - clientID: 'c51bc9c9-e81c-4263-887e-7cc68ab8e185', - clientSecret: '99a8bb9d-b622-4ea7-a46c-77b74f98ce80', - callbackURL: 'http://localhost:3333/oauth/hubspot/callback', - redirectUri: 'http://localhost:3333/oauth/hubspot/callback', + clientID: oauthSecrets.hubspot.client_id, + clientSecret: oauthSecrets.hubspot.client_secret, + callbackURL: oauthSecrets.hubspot.redirect_uri, + redirectUri: oauthSecrets.hubspot.redirect_uri, scope: 'automation business-intelligence oauth forms integration-sync sales-email-read crm.lists.read crm.objects.contacts.read crm.schemas.contacts.read crm.objects.companies.read crm.objects.deals.read crm.schemas.companies.read crm.schemas.deals.read crm.objects.owners.read crm.objects.quotes.read crm.schemas.quotes.read crm.objects.line_items.read crm.schemas.line_items.read', passReqToCallback: true, @@ -22,7 +26,8 @@ export class HubspotStrategy extends PassportStrategy(Strategy) { } authenticate(req, options) { - options.state = 'customer_id'; + const { customer_id } = req.query; + options.state = customer_id; super.authenticate(req, options); } } diff --git a/src/utils/OauthSecrets.ts b/src/utils/OauthSecrets.ts index a79cc5a..39e5415 100644 --- a/src/utils/OauthSecrets.ts +++ b/src/utils/OauthSecrets.ts @@ -8,22 +8,24 @@ class OauthSecretsObject { client_secret = ''; redirect_uri = ''; } - -export class OauthScrets { +// @Injectable() +export class OauthSecrets { hubspot = new OauthSecretsObject(); google = new OauthSecretsObject(); mailchimp = new OauthSecretsObject(); - async init() { - const path = process.env.SM_OAUTH_PATH; - const secretsManagerClient = new SecretsManagerClient({}); - for (const key in this) { - const getSecretComand = new GetSecretValueCommand({ - SecretId: `${path}/${key}`, - }); - const res = await secretsManagerClient - .send(getSecretComand) - .catch(() => null); - if (res) this[key] = JSON.parse(res.SecretString); - } +} +export async function getOauthSecrets() { + const secrets = new OauthSecrets(); + const path = process.env.SM_OAUTH_PATH; + const secretsManagerClient = new SecretsManagerClient({}); + for (const key in secrets) { + const getSecretComand = new GetSecretValueCommand({ + SecretId: `${path}/${key}`, + }); + const res = await secretsManagerClient + .send(getSecretComand) + .catch(() => null); + if (res) secrets[key] = JSON.parse(res.SecretString); } + return secrets; } diff --git a/swagger.json b/swagger.json index d6137f4..a36331c 100644 --- a/swagger.json +++ b/swagger.json @@ -1 +1 @@ -{"openapi":"3.0.0","paths":{"/inputs/available-entities/{plugin}":{"get":{"operationId":"InputsController_getAvailableEntities","parameters":[{"name":"plugin","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAvailableEntitiesRes"}}}}},"tags":["inputs"]}},"/inputs/test-connection":{"post":{"operationId":"InputsController_testConnection","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestConnectionReq"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestConnectionRes"}}}}},"tags":["inputs"]}},"/inputs/test-connection/get-columns":{"post":{"operationId":"InputsController_getColumns","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestConnectionGetColumnsReq"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestConnectionGetColumnsRes"}}}}},"tags":["inputs"]}},"/inputs":{"post":{"operationId":"InputsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInputReq"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Input"}}}}},"tags":["inputs"]},"get":{"operationId":"InputsController_findAll","parameters":[],"responses":{"200":{"description":""}},"tags":["inputs"]}},"/inputs/{id}":{"get":{"operationId":"InputsController_findOne","parameters":[],"responses":{"200":{"description":""}},"tags":["inputs"]},"patch":{"operationId":"InputsController_update","parameters":[],"responses":{"200":{"description":""}},"tags":["inputs"]},"delete":{"operationId":"InputsController_delete","parameters":[],"responses":{"200":{"description":""}},"tags":["inputs"]}},"/transformations":{"post":{"operationId":"TransformationsController_create","parameters":[],"responses":{"201":{"description":""}}},"get":{"operationId":"TransformationsController_findAll","parameters":[],"responses":{"200":{"description":""}}}},"/transformations/{id}":{"get":{"operationId":"TransformationsController_findOne","parameters":[],"responses":{"200":{"description":""}}},"put":{"operationId":"TransformationsController_update","parameters":[],"responses":{"200":{"description":""}}},"delete":{"operationId":"TransformationsController_delete","parameters":[],"responses":{"200":{"description":""}}}},"/outputs":{"post":{"operationId":"OutputsController_create","parameters":[],"responses":{"201":{"description":""}}},"get":{"operationId":"OutputsController_findAll","parameters":[],"responses":{"200":{"description":""}}}},"/outputs/{id}":{"get":{"operationId":"OutputsController_findOne","parameters":[],"responses":{"200":{"description":""}}},"put":{"operationId":"OutputsController_update","parameters":[],"responses":{"200":{"description":""}}},"delete":{"operationId":"OutputsController_delete","parameters":[],"responses":{"200":{"description":""}}}},"/pipelines/start/{id}":{"post":{"operationId":"PipelinesController_activate","parameters":[],"responses":{"201":{"description":""}}}},"/pipelines/{id}/status":{"get":{"operationId":"PipelinesController_getPipelineStatus","parameters":[],"responses":{"200":{"description":""}}}},"/pipelines/{id}/{details}":{"get":{"operationId":"PipelinesController_getPipelineLogs","parameters":[],"responses":{"200":{"description":""}}}},"/pipelines":{"post":{"operationId":"PipelinesController_create","parameters":[],"responses":{"201":{"description":""}}},"get":{"operationId":"PipelinesController_findAll","parameters":[],"responses":{"200":{"description":""}}}},"/pipelines/{id}":{"get":{"operationId":"PipelinesController_findOne","parameters":[],"responses":{"200":{"description":""}}},"put":{"operationId":"PipelinesController_update","parameters":[],"responses":{"200":{"description":""}}},"delete":{"operationId":"PipelinesController_delete","parameters":[],"responses":{"200":{"description":""}}}},"/auth":{"post":{"operationId":"AuthController_signIn_old","parameters":[],"responses":{"200":{"description":""}}}},"/auth/login":{"post":{"operationId":"AuthController_signIn_login","parameters":[],"responses":{"200":{"description":""}}}},"/auth/sign-in":{"post":{"operationId":"AuthController_signIn","parameters":[],"responses":{"200":{"description":""}}}},"/auth/refresh-access-token":{"post":{"operationId":"AuthController_refreshAccessToken","parameters":[],"responses":{"200":{"description":""}}}},"/auth/enable-totp":{"post":{"operationId":"AuthController_enableTotpMFA","parameters":[],"responses":{"200":{"description":""}}}},"/auth/disable-totp":{"post":{"operationId":"AuthController_disableTotpMFA","parameters":[],"responses":{"200":{"description":""}}}},"/auth/dismiss-totp":{"post":{"operationId":"AuthController_dismissTotpMFA","parameters":[],"responses":{"200":{"description":""}}}},"/auth/verify-totp":{"post":{"operationId":"AuthController_verifyTotp","parameters":[],"responses":{"200":{"description":""}}}},"/auth/change-password":{"post":{"operationId":"AuthController_changePassword","parameters":[],"responses":{"200":{"description":""}}}},"/auth/reset-password":{"post":{"operationId":"AuthController_resetPassword","parameters":[],"responses":{"200":{"description":""}}}},"/auth/verify-reset-password-code":{"post":{"operationId":"AuthController_verifyResetPasswordCode","parameters":[],"responses":{"200":{"description":""}}}},"/auth/confirm-reset-password":{"post":{"operationId":"AuthController_confirmResetPassword","parameters":[],"responses":{"200":{"description":""}}}},"/health":{"get":{"operationId":"HealthController_check","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/all":{"get":{"operationId":"CatalogController_catalogAll","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data_apps":{"get":{"operationId":"CatalogController_dataAppsAll","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data_apps/{id}":{"delete":{"operationId":"CatalogController_dataAppsOne","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/dashboard-metabase":{"get":{"operationId":"CatalogController_getAllDashboardMetabase","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/dashboard-metabase/{id}":{"get":{"operationId":"CatalogController_getOneDashboardMetabase","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-metadata":{"get":{"operationId":"CatalogController_getAllTableMetadata","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-metadata/{id}":{"delete":{"operationId":"CatalogController_deleteOneTableMetadata","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/column-metadata":{"get":{"operationId":"CatalogController_getOneColumnMetadata","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/column-metadata/{id}":{"delete":{"operationId":"CatalogController_deleteOneColumnMetadata","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data-preview":{"get":{"operationId":"CatalogController_getOneDataPreview","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data-status":{"get":{"operationId":"CatalogController_createDataStatus","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data-description":{"get":{"operationId":"CatalogController_getDataDescription","parameters":[],"responses":{"200":{"description":""}}},"post":{"operationId":"CatalogController_createDataDescription","parameters":[],"responses":{"201":{"description":""}}}},"/catalog/data-docs":{"get":{"operationId":"CatalogController_getDataDocs","parameters":[],"responses":{"200":{"description":""}}},"post":{"operationId":"CatalogController_createDataDocs","parameters":[],"responses":{"201":{"description":""}}}},"/catalog/data-rating":{"get":{"operationId":"CatalogController_getDataRating","parameters":[],"responses":{"200":{"description":""}}},"post":{"operationId":"CatalogController_createDataRating","parameters":[],"responses":{"201":{"description":""}}}},"/catalog/summary-rating/{id}":{"get":{"operationId":"CatalogController_getSummaryRating","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data-comment":{"get":{"operationId":"CatalogController_getDataComment","parameters":[],"responses":{"200":{"description":""}}},"post":{"operationId":"CatalogController_createDataComment","parameters":[],"responses":{"201":{"description":""}}}},"/catalog/data-review":{"get":{"operationId":"CatalogController_getDataReview","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/tags":{"post":{"operationId":"CatalogController_createTags","parameters":[],"responses":{"201":{"description":""}}},"get":{"operationId":"CatalogController_findAllTags","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/tags/{id}":{"delete":{"operationId":"CatalogController_deleteTags","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-tags":{"post":{"operationId":"CatalogController_createTableTags","parameters":[],"responses":{"201":{"description":""}}},"get":{"operationId":"CatalogController_getAllTableTags","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-tags/{id}":{"delete":{"operationId":"CatalogController_deleteTableTags","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-rules":{"get":{"operationId":"CatalogController_getTableRules","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-rules/{id}":{"delete":{"operationId":"CatalogController_deleteTableRules","parameters":[],"responses":{"200":{"description":""}}}},"/oauth/hubspot":{"get":{"operationId":"OauthController_oauthHubspot","parameters":[],"responses":{"200":{"description":""}},"tags":["oauth"]}},"/oauth/hubspot/callback":{"get":{"operationId":"OauthController_oauthHubspotCallback","parameters":[],"responses":{"200":{"description":""}},"tags":["oauth"]}}},"info":{"title":"Maestro Grpc Documentation","description":"Documentation for Maestro gateway","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"GetAvailableEntitiesRes":{"type":"object","properties":{"entities":{"type":"array","items":{"type":"string"}}},"required":["entities"]},"CredentialsJdbc":{"type":"object","properties":{"jdbc_user":{"type":"string"},"jdbc_password":{"type":"string"},"database":{"type":"string"},"endpoint":{"type":"string"},"port":{"type":"string"},"engine":{"type":"string"},"schema":{"type":"string"}}},"TestConnectionReq":{"type":"object","properties":{"plugin":{"type":"string"},"credentials":{"$ref":"#/components/schemas/CredentialsJdbc"}},"required":["plugin","credentials"]},"TestConnectionRes":{"type":"object","properties":{"connection_state":{"type":"boolean"},"total_entities":{"type":"number"},"database_tables":{"type":"array","items":{"type":"string"}}},"required":["connection_state","total_entities","database_tables"]},"TestConnectionGetColumnsReq":{"type":"object","properties":{"plugin":{"type":"string"},"tables":{"type":"array","items":{"type":"string"}},"credentials":{"$ref":"#/components/schemas/CredentialsJdbc"},"id":{"type":"string"}},"required":["plugin","tables"]},"TestConnectionGetColumnsRes":{"type":"object","properties":{"tables":{"type":"array","items":{"type":"string"}}},"required":["tables"]},"FileFormatParams":{"type":"object","properties":{"file_format":{"type":"string"},"encoding":{"type":"string"}}},"GoogleAnalyticsClientSecrets":{"type":"object","properties":{"type":{"type":"string"},"project_id":{"type":"string"},"private_key_id":{"type":"string"},"private_key":{"type":"string"},"client_email":{"type":"string"},"client_id":{"type":"string"},"auth_uri":{"type":"string"},"token_uri":{"type":"string"},"auth_provider_x509_cert_url":{"type":"string"},"client_x509_cert_url":{"type":"string"}},"required":["type","project_id","private_key_id","private_key","client_email","client_id","auth_uri","token_uri","auth_provider_x509_cert_url","client_x509_cert_url"]},"Credentials":{"type":"object","properties":{"jdbc_user":{"type":"string"},"jdbc_password":{"type":"string"},"database":{"type":"string"},"endpoint":{"type":"string"},"port":{"type":"string"},"engine":{"type":"string"},"schema":{"type":"string"},"connection_type":{"type":"string"},"client_aws_access_key_id":{"type":"string"},"client_aws_secret_access_key":{"type":"string"},"client_bucket":{"type":"string"},"file_to_extract":{"type":"string"},"file_format_params":{"$ref":"#/components/schemas/FileFormatParams"},"view_id":{"type":"string"},"client_secrets":{"$ref":"#/components/schemas/GoogleAnalyticsClientSecrets"},"start_date":{"type":"string"},"end_date":{"type":"string"},"oauth_code":{"type":"string"}},"required":["connection_type"]},"OauthObject":{"type":"object","properties":{"get_tokens_url":{"type":"string"},"get_tokens_url_params":{"type":"string"},"get_tokens_set_response":{"type":"object"},"content_type":{"type":"string"}}},"InputOptions":{"type":"object","properties":{"oauth":{"$ref":"#/components/schemas/OauthObject"},"skip_select_columns":{"type":"boolean"},"skip_select_entities":{"type":"boolean"},"skip_transformation":{"type":"boolean"}}},"CreateInputReq":{"type":"object","properties":{"plugin":{"type":"string"},"category":{"type":"string"},"credentials":{"$ref":"#/components/schemas/Credentials"},"name":{"type":"string"},"options":{"$ref":"#/components/schemas/InputOptions"}},"required":["plugin","category","credentials","name"]},"Input":{"type":"object","properties":{"id":{"type":"string"},"category":{"type":"string"},"plugin":{"type":"string"},"name":{"type":"string"},"cron":{"type":"string"},"credentials":{"$ref":"#/components/schemas/Credentials"},"client_id":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","category","plugin","name","cron","credentials","client_id","created_at","updated_at"]}}}} \ No newline at end of file +{"openapi":"3.0.0","paths":{"/inputs/available-entities/{plugin}":{"get":{"operationId":"InputsController_getAvailableEntities","parameters":[{"name":"plugin","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetAvailableEntitiesRes"}}}}},"tags":["inputs"]}},"/inputs/test-connection":{"post":{"operationId":"InputsController_testConnection","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestConnectionReq"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestConnectionRes"}}}}},"tags":["inputs"]}},"/inputs/test-connection/get-columns":{"post":{"operationId":"InputsController_getColumns","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestConnectionGetColumnsReq"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestConnectionGetColumnsRes"}}}}},"tags":["inputs"]}},"/inputs":{"post":{"operationId":"InputsController_create","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInputReq"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Input"}}}}},"tags":["inputs"]},"get":{"operationId":"InputsController_findAll","parameters":[],"responses":{"200":{"description":""}},"tags":["inputs"]}},"/inputs/{id}":{"post":{"operationId":"InputsController_reCreate","parameters":[{"name":"id","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInputReq"}}}},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Input"}}}}},"tags":["inputs"]},"get":{"operationId":"InputsController_findOne","parameters":[],"responses":{"200":{"description":""}},"tags":["inputs"]},"patch":{"operationId":"InputsController_update","parameters":[],"responses":{"200":{"description":""}},"tags":["inputs"]},"delete":{"operationId":"InputsController_delete","parameters":[],"responses":{"200":{"description":""}},"tags":["inputs"]}},"/transformations":{"post":{"operationId":"TransformationsController_create","parameters":[],"responses":{"201":{"description":""}}},"get":{"operationId":"TransformationsController_findAll","parameters":[],"responses":{"200":{"description":""}}}},"/transformations/{id}":{"get":{"operationId":"TransformationsController_findOne","parameters":[],"responses":{"200":{"description":""}}},"put":{"operationId":"TransformationsController_update","parameters":[],"responses":{"200":{"description":""}}},"delete":{"operationId":"TransformationsController_delete","parameters":[],"responses":{"200":{"description":""}}}},"/outputs":{"post":{"operationId":"OutputsController_create","parameters":[],"responses":{"201":{"description":""}}},"get":{"operationId":"OutputsController_findAll","parameters":[],"responses":{"200":{"description":""}}}},"/outputs/{id}":{"get":{"operationId":"OutputsController_findOne","parameters":[],"responses":{"200":{"description":""}}},"put":{"operationId":"OutputsController_update","parameters":[],"responses":{"200":{"description":""}}},"delete":{"operationId":"OutputsController_delete","parameters":[],"responses":{"200":{"description":""}}}},"/pipelines/start/{id}":{"post":{"operationId":"PipelinesController_activate","parameters":[],"responses":{"201":{"description":""}}}},"/pipelines/{id}/status":{"get":{"operationId":"PipelinesController_getPipelineStatus","parameters":[],"responses":{"200":{"description":""}}}},"/pipelines/{id}/{details}":{"get":{"operationId":"PipelinesController_getPipelineLogs","parameters":[],"responses":{"200":{"description":""}}}},"/pipelines":{"post":{"operationId":"PipelinesController_create","parameters":[],"responses":{"201":{"description":""}}},"get":{"operationId":"PipelinesController_findAll","parameters":[],"responses":{"200":{"description":""}}}},"/pipelines/{id}":{"get":{"operationId":"PipelinesController_findOne","parameters":[],"responses":{"200":{"description":""}}},"put":{"operationId":"PipelinesController_update","parameters":[],"responses":{"200":{"description":""}}},"delete":{"operationId":"PipelinesController_delete","parameters":[],"responses":{"200":{"description":""}}}},"/auth":{"post":{"operationId":"AuthController_signIn_old","parameters":[],"responses":{"200":{"description":""}}}},"/auth/login":{"post":{"operationId":"AuthController_signIn_login","parameters":[],"responses":{"200":{"description":""}}}},"/auth/sign-in":{"post":{"operationId":"AuthController_signIn","parameters":[],"responses":{"200":{"description":""}}}},"/auth/refresh-access-token":{"post":{"operationId":"AuthController_refreshAccessToken","parameters":[],"responses":{"200":{"description":""}}}},"/auth/enable-totp":{"post":{"operationId":"AuthController_enableTotpMFA","parameters":[],"responses":{"200":{"description":""}}}},"/auth/disable-totp":{"post":{"operationId":"AuthController_disableTotpMFA","parameters":[],"responses":{"200":{"description":""}}}},"/auth/dismiss-totp":{"post":{"operationId":"AuthController_dismissTotpMFA","parameters":[],"responses":{"200":{"description":""}}}},"/auth/verify-totp":{"post":{"operationId":"AuthController_verifyTotp","parameters":[],"responses":{"200":{"description":""}}}},"/auth/change-password":{"post":{"operationId":"AuthController_changePassword","parameters":[],"responses":{"200":{"description":""}}}},"/auth/reset-password":{"post":{"operationId":"AuthController_resetPassword","parameters":[],"responses":{"200":{"description":""}}}},"/auth/verify-reset-password-code":{"post":{"operationId":"AuthController_verifyResetPasswordCode","parameters":[],"responses":{"200":{"description":""}}}},"/auth/confirm-reset-password":{"post":{"operationId":"AuthController_confirmResetPassword","parameters":[],"responses":{"200":{"description":""}}}},"/health":{"get":{"operationId":"HealthController_check","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/all":{"get":{"operationId":"CatalogController_catalogAll","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data_apps":{"get":{"operationId":"CatalogController_dataAppsAll","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data_apps/{id}":{"delete":{"operationId":"CatalogController_dataAppsOne","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/dashboard-metabase":{"get":{"operationId":"CatalogController_getAllDashboardMetabase","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/dashboard-metabase/{id}":{"get":{"operationId":"CatalogController_getOneDashboardMetabase","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-metadata":{"get":{"operationId":"CatalogController_getAllTableMetadata","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-metadata/{id}":{"delete":{"operationId":"CatalogController_deleteOneTableMetadata","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/column-metadata":{"get":{"operationId":"CatalogController_getOneColumnMetadata","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/column-metadata/{id}":{"delete":{"operationId":"CatalogController_deleteOneColumnMetadata","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data-preview":{"get":{"operationId":"CatalogController_getOneDataPreview","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data-status":{"get":{"operationId":"CatalogController_createDataStatus","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data-description":{"get":{"operationId":"CatalogController_getDataDescription","parameters":[],"responses":{"200":{"description":""}}},"post":{"operationId":"CatalogController_createDataDescription","parameters":[],"responses":{"201":{"description":""}}}},"/catalog/data-docs":{"get":{"operationId":"CatalogController_getDataDocs","parameters":[],"responses":{"200":{"description":""}}},"post":{"operationId":"CatalogController_createDataDocs","parameters":[],"responses":{"201":{"description":""}}}},"/catalog/data-rating":{"get":{"operationId":"CatalogController_getDataRating","parameters":[],"responses":{"200":{"description":""}}},"post":{"operationId":"CatalogController_createDataRating","parameters":[],"responses":{"201":{"description":""}}}},"/catalog/summary-rating/{id}":{"get":{"operationId":"CatalogController_getSummaryRating","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/data-comment":{"get":{"operationId":"CatalogController_getDataComment","parameters":[],"responses":{"200":{"description":""}}},"post":{"operationId":"CatalogController_createDataComment","parameters":[],"responses":{"201":{"description":""}}}},"/catalog/data-review":{"get":{"operationId":"CatalogController_getDataReview","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/tags":{"post":{"operationId":"CatalogController_createTags","parameters":[],"responses":{"201":{"description":""}}},"get":{"operationId":"CatalogController_findAllTags","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/tags/{id}":{"delete":{"operationId":"CatalogController_deleteTags","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-tags":{"post":{"operationId":"CatalogController_createTableTags","parameters":[],"responses":{"201":{"description":""}}},"get":{"operationId":"CatalogController_getAllTableTags","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-tags/{id}":{"delete":{"operationId":"CatalogController_deleteTableTags","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-rules":{"get":{"operationId":"CatalogController_getTableRules","parameters":[],"responses":{"200":{"description":""}}}},"/catalog/table-rules/{id}":{"delete":{"operationId":"CatalogController_deleteTableRules","parameters":[],"responses":{"200":{"description":""}}}},"/oauth/hubspot":{"get":{"operationId":"OauthController_oauthHubspot","parameters":[],"responses":{"200":{"description":""}},"tags":["oauth"]}},"/oauth/hubspot/callback":{"get":{"operationId":"OauthController_oauthHubspotCallback","parameters":[],"responses":{"200":{"description":""}},"tags":["oauth"]}}},"info":{"title":"Maestro Grpc Documentation","description":"Documentation for Maestro gateway","version":"1.0","contact":{}},"tags":[],"servers":[],"components":{"securitySchemes":{"bearer":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"GetAvailableEntitiesRes":{"type":"object","properties":{"entities":{"type":"array","items":{"type":"string"}}},"required":["entities"]},"CredentialsJdbc":{"type":"object","properties":{"jdbc_user":{"type":"string"},"jdbc_password":{"type":"string"},"database":{"type":"string"},"endpoint":{"type":"string"},"port":{"type":"string"},"engine":{"type":"string"},"schema":{"type":"string"}}},"TestConnectionReq":{"type":"object","properties":{"plugin":{"type":"string"},"credentials":{"$ref":"#/components/schemas/CredentialsJdbc"}},"required":["plugin","credentials"]},"TestConnectionRes":{"type":"object","properties":{"connection_state":{"type":"boolean"},"total_entities":{"type":"number"},"database_tables":{"type":"array","items":{"type":"string"}}},"required":["connection_state","total_entities","database_tables"]},"TestConnectionGetColumnsReq":{"type":"object","properties":{"plugin":{"type":"string"},"tables":{"type":"array","items":{"type":"string"}},"credentials":{"$ref":"#/components/schemas/CredentialsJdbc"},"id":{"type":"string"}},"required":["plugin","tables"]},"TestConnectionGetColumnsRes":{"type":"object","properties":{"tables":{"type":"array","items":{"type":"string"}}},"required":["tables"]},"FileFormatParams":{"type":"object","properties":{"file_format":{"type":"string"},"encoding":{"type":"string"}}},"GoogleAnalyticsClientSecrets":{"type":"object","properties":{"type":{"type":"string"},"project_id":{"type":"string"},"private_key_id":{"type":"string"},"private_key":{"type":"string"},"client_email":{"type":"string"},"client_id":{"type":"string"},"auth_uri":{"type":"string"},"token_uri":{"type":"string"},"auth_provider_x509_cert_url":{"type":"string"},"client_x509_cert_url":{"type":"string"}},"required":["type","project_id","private_key_id","private_key","client_email","client_id","auth_uri","token_uri","auth_provider_x509_cert_url","client_x509_cert_url"]},"Credentials":{"type":"object","properties":{"jdbc_user":{"type":"string"},"jdbc_password":{"type":"string"},"database":{"type":"string"},"endpoint":{"type":"string"},"port":{"type":"string"},"engine":{"type":"string"},"schema":{"type":"string"},"connection_type":{"type":"string"},"client_aws_access_key_id":{"type":"string"},"client_aws_secret_access_key":{"type":"string"},"client_bucket":{"type":"string"},"file_to_extract":{"type":"string"},"file_format_params":{"$ref":"#/components/schemas/FileFormatParams"},"view_id":{"type":"string"},"client_secrets":{"$ref":"#/components/schemas/GoogleAnalyticsClientSecrets"},"start_date":{"type":"string"},"end_date":{"type":"string"},"oauth_code":{"type":"string"}},"required":["connection_type"]},"OauthObject":{"type":"object","properties":{"get_tokens_url":{"type":"string"},"get_tokens_url_params":{"type":"string"},"get_tokens_set_response":{"type":"object"},"content_type":{"type":"string"}}},"InputOptions":{"type":"object","properties":{"oauth":{"$ref":"#/components/schemas/OauthObject"},"skip_select_columns":{"type":"boolean"},"skip_select_entities":{"type":"boolean"},"skip_transformation":{"type":"boolean"}}},"CreateInputReq":{"type":"object","properties":{"id":{"type":"string"},"plugin":{"type":"string"},"category":{"type":"string"},"credentials":{"$ref":"#/components/schemas/Credentials"},"name":{"type":"string"},"options":{"$ref":"#/components/schemas/InputOptions"}},"required":["plugin","category","credentials","name"]},"Input":{"type":"object","properties":{"id":{"type":"string"},"category":{"type":"string"},"plugin":{"type":"string"},"name":{"type":"string"},"cron":{"type":"string"},"credentials":{"$ref":"#/components/schemas/Credentials"},"client_id":{"type":"string"},"created_at":{"type":"string"},"updated_at":{"type":"string"}},"required":["id","category","plugin","name","cron","credentials","client_id","created_at","updated_at"]}}}} \ No newline at end of file