mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-24 09:28:31 +00:00
* initial commit * multi env changes * multi-env changes * entity fixes * data query changes * fix * trying to avoid conflict with EE * moved version creation to app creation function * fixing some issues * execution of data query * revert options changes * changed migration * fixed some migration issues: testing migration * multi env support * app import export fix * fixes * migration fixes * removed plugins from data query * fixing some migration issues * fixes * remove console log * fix * front end api changes * backward compatibility for app import * Fixed a bug * correcting some mistakes * Added constraints and fixed some issues * changes * fix for data source listing * fixing version operation issues * remove kind from data query * removed kind from data query * fixes * fixes * fix for version creation * migration fixes * Fixed preview and run query issues * Fix: new version and event query id issue * fixed rest api oauth issue - next test refresh token * import export changes * fixes for app import * import fix * added await for for loops * fix * fix for migration * Fixed backend oauth-envId issue * import export changes * migration fixes * fix * fix * fix for app import from 0.9.0 * test case fixes * test case fixes * making app name mandatory for import * adding type for options * fix: imported apps query linking issues * review changes * lint issue fixes * added on delete cascade Co-authored-by: Muhsin Shah <muhsinshah21@gmail.com>
235 lines
7.5 KiB
TypeScript
235 lines
7.5 KiB
TypeScript
import {
|
|
Controller,
|
|
Get,
|
|
Param,
|
|
Body,
|
|
Post,
|
|
Patch,
|
|
Delete,
|
|
Query,
|
|
UseGuards,
|
|
ForbiddenException,
|
|
BadRequestException,
|
|
} from '@nestjs/common';
|
|
import { JwtAuthGuard } from '../../src/modules/auth/jwt-auth.guard';
|
|
import { decamelizeKeys } from 'humps';
|
|
import { DataQueriesService } from '../../src/services/data_queries.service';
|
|
import { DataSourcesService } from '../../src/services/data_sources.service';
|
|
import { QueryAuthGuard } from 'src/modules/auth/query-auth.guard';
|
|
import { AppsAbilityFactory } from 'src/modules/casl/abilities/apps-ability.factory';
|
|
import { AppsService } from '@services/apps.service';
|
|
import { CreateDataQueryDto, UpdateDataQueryDto } from '@dto/data-query.dto';
|
|
import { User } from 'src/decorators/user.decorator';
|
|
import { decode } from 'js-base64';
|
|
import { dbTransactionWrap } from 'src/helpers/utils.helper';
|
|
import { EntityManager } from 'typeorm';
|
|
import { DataSource } from 'src/entities/data_source.entity';
|
|
|
|
@Controller('data_queries')
|
|
export class DataQueriesController {
|
|
constructor(
|
|
private appsService: AppsService,
|
|
private dataQueriesService: DataQueriesService,
|
|
private dataSourcesService: DataSourcesService,
|
|
private appsAbilityFactory: AppsAbilityFactory
|
|
) {}
|
|
|
|
@UseGuards(JwtAuthGuard)
|
|
@Get()
|
|
async index(@User() user, @Query() query) {
|
|
const app = await this.appsService.findAppFromVersion(query.app_version_id);
|
|
const ability = await this.appsAbilityFactory.appsActions(user, app.id);
|
|
|
|
if (!ability.can('getQueries', app)) {
|
|
throw new ForbiddenException('you do not have permissions to perform this action');
|
|
}
|
|
|
|
const queries = await this.dataQueriesService.all(query);
|
|
const seralizedQueries = [];
|
|
|
|
// serialize
|
|
for (const query of queries) {
|
|
if (query.dataSource.kind === 'runjsdefault' || query.dataSource.kind === 'restapidefault') {
|
|
delete query['dataSourceId'];
|
|
}
|
|
delete query['dataSource'];
|
|
|
|
const decamelizedQuery = decamelizeKeys(query);
|
|
|
|
decamelizedQuery['options'] = query.options;
|
|
|
|
if (query.plugin) {
|
|
decamelizedQuery['plugin'].manifest_file.data = JSON.parse(
|
|
decode(query.plugin.manifestFile.data.toString('utf8'))
|
|
);
|
|
decamelizedQuery['plugin'].icon_file.data = query.plugin.iconFile.data.toString('utf8');
|
|
}
|
|
|
|
seralizedQueries.push(decamelizedQuery);
|
|
}
|
|
|
|
const response = { data_queries: seralizedQueries };
|
|
|
|
return response;
|
|
}
|
|
|
|
@UseGuards(JwtAuthGuard)
|
|
@Post()
|
|
async create(@User() user, @Body() dataQueryDto: CreateDataQueryDto): Promise<object> {
|
|
const {
|
|
kind,
|
|
name,
|
|
options,
|
|
data_source_id: dataSourceId,
|
|
plugin_id: pluginId,
|
|
app_version_id: appVersionId,
|
|
} = dataQueryDto;
|
|
|
|
let dataSource: DataSource;
|
|
|
|
if (!dataSourceId && !(kind === 'restapi' || kind === 'runjs')) {
|
|
throw new BadRequestException();
|
|
}
|
|
|
|
return dbTransactionWrap(async (manager: EntityManager) => {
|
|
if (!dataSourceId && (kind === 'restapi' || kind === 'runjs')) {
|
|
dataSource = await this.dataSourcesService.findDefaultDataSource(kind, appVersionId, pluginId, manager);
|
|
}
|
|
|
|
const app = await this.dataSourcesService.findApp(dataSource?.id || dataSourceId, manager);
|
|
const ability = await this.appsAbilityFactory.appsActions(user, app.id);
|
|
|
|
if (!ability.can('createQuery', app)) {
|
|
throw new ForbiddenException('you do not have permissions to perform this action');
|
|
}
|
|
|
|
// todo: pass the whole dto instead of indv. values
|
|
const dataQuery = await this.dataQueriesService.create(name, options, dataSource?.id || dataSourceId, manager);
|
|
return decamelizeKeys(dataQuery);
|
|
});
|
|
}
|
|
|
|
@UseGuards(JwtAuthGuard)
|
|
@Patch(':id')
|
|
async update(@User() user, @Param('id') dataQueryId, @Body() updateDataQueryDto: UpdateDataQueryDto) {
|
|
const { name, options } = updateDataQueryDto;
|
|
|
|
const dataQuery = await this.dataQueriesService.findOne(dataQueryId);
|
|
const ability = await this.appsAbilityFactory.appsActions(user, dataQuery.dataSource.app.id);
|
|
|
|
if (!ability.can('updateQuery', dataQuery.dataSource.app)) {
|
|
throw new ForbiddenException('you do not have permissions to perform this action');
|
|
}
|
|
|
|
const result = await this.dataQueriesService.update(dataQueryId, name, options);
|
|
return decamelizeKeys(result);
|
|
}
|
|
|
|
@UseGuards(JwtAuthGuard)
|
|
@Delete(':id')
|
|
async delete(@User() user, @Param('id') dataQueryId) {
|
|
const dataQuery = await this.dataQueriesService.findOne(dataQueryId);
|
|
const ability = await this.appsAbilityFactory.appsActions(user, dataQuery.dataSource.app.id);
|
|
|
|
if (!ability.can('deleteQuery', dataQuery.dataSource.app)) {
|
|
throw new ForbiddenException('you do not have permissions to perform this action');
|
|
}
|
|
|
|
const result = await this.dataQueriesService.delete(dataQueryId);
|
|
return decamelizeKeys(result);
|
|
}
|
|
|
|
@UseGuards(QueryAuthGuard)
|
|
@Post([':id/run/:environmentId', ':id/run'])
|
|
async runQuery(
|
|
@User() user,
|
|
@Param('id') dataQueryId,
|
|
@Param('environmentId') environmentId,
|
|
@Body() updateDataQueryDto: UpdateDataQueryDto
|
|
) {
|
|
const { options } = updateDataQueryDto;
|
|
|
|
const dataQuery = await this.dataQueriesService.findOne(dataQueryId);
|
|
|
|
if (user) {
|
|
const ability = await this.appsAbilityFactory.appsActions(user, dataQuery.dataSource.app.id);
|
|
|
|
if (!ability.can('runQuery', dataQuery.dataSource.app)) {
|
|
throw new ForbiddenException('you do not have permissions to perform this action');
|
|
}
|
|
}
|
|
|
|
let result = {};
|
|
|
|
try {
|
|
result = await this.dataQueriesService.runQuery(user, dataQuery, options, environmentId);
|
|
} catch (error) {
|
|
if (error.constructor.name === 'QueryError') {
|
|
result = {
|
|
status: 'failed',
|
|
message: error.message,
|
|
description: error.description,
|
|
data: error.data,
|
|
};
|
|
} else {
|
|
console.log(error);
|
|
result = {
|
|
status: 'failed',
|
|
message: 'Internal server error',
|
|
description: error.message,
|
|
data: {},
|
|
};
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
@UseGuards(JwtAuthGuard)
|
|
@Post(['/preview/:environmentId', '/preview'])
|
|
async previewQuery(
|
|
@User() user,
|
|
@Body() updateDataQueryDto: UpdateDataQueryDto,
|
|
@Param('environmentId') environmentId
|
|
) {
|
|
const { options, query } = updateDataQueryDto;
|
|
const kind = query ? query['kind'] : null;
|
|
const dataQueryEntity = {
|
|
...query,
|
|
dataSource: query['data_source_id']
|
|
? await this.dataSourcesService.findOne(query['data_source_id'])
|
|
: await this.dataSourcesService.findDatasourceByKind(`${kind}default`, environmentId),
|
|
};
|
|
|
|
const ability = await this.appsAbilityFactory.appsActions(user, dataQueryEntity.dataSource.app.id);
|
|
|
|
if (!ability.can('previewQuery', dataQueryEntity.dataSource.app)) {
|
|
throw new ForbiddenException('you do not have permissions to perform this action');
|
|
}
|
|
|
|
let result = {};
|
|
|
|
try {
|
|
result = await this.dataQueriesService.runQuery(user, dataQueryEntity, options, environmentId);
|
|
} catch (error) {
|
|
if (error.constructor.name === 'QueryError') {
|
|
result = {
|
|
status: 'failed',
|
|
message: error.message,
|
|
description: error.description,
|
|
data: error.data,
|
|
};
|
|
} else {
|
|
console.log(error);
|
|
result = {
|
|
status: 'failed',
|
|
message: 'Internal server error',
|
|
description: error.message,
|
|
data: {},
|
|
};
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|