ToolJet/server/src/controllers/plugins.controller.ts
Gandharv a1fd1fc301
[Feature] Make plugins installable (#3069)
* feat: add user avatar

* update: @nest/platform-express from 8.0.0 to 8.4.4

* add avatar_id in login response

* add user avatar upload in frontend

* align cross divider with layout icons'

* generate nest model - extensions

* Add extensions module

* Add extension to datasouce

* add not implemented check

* create extension

* refactor

* cleanup

* fix tests

* reduce the avatar size on homepage

* poc: run js code from string

* resolve conflicts

* fix conflicts

* add globals

* add new route

* add icon, manifest file upload

* complete user flow

* add flow for data queries

* add dynamic manifest instead of local datasource types

* add version attr

* remove unused code

* add version

* rename extension(s) -> plugins(s)

* add test connection method

* feat: add marketplace listing page

* Add install plugin cmd + missing attrs {name, repo, desc} to plugin

* add missing icon

* - Add npm workspaces for marketplace monorepo
- Added cassandra datasource plugin
- Created upload to s3 script
- Created plugins.json entry file

* install plugin from s3 bucket

* cleanup

* update pkg locks

* fix icon render

* cleanup

* marketplace changes

* ui changes

* operations file load fix + revert vm2

* update module from string to 3.2.1

* load plugins.json from local file instead of remote

* install plugin from local file if not production environment

* add sqlite

* feat: add plivo api plugin

* exp: add heroku 22 stack

* update assets include path

* Revert "exp: add heroku 22 stack"

This reverts commit a8926b36e1.

* add integrations link

* Add casl ability for plugin

* load host from env else fallback to default

* update imports

* remove sqlite

* typo

* add marketplace flag to cli command

* move ts and ncc to devDep

* add hygen templates for marketplace

* cli tree-node path fix

* template indent fix

* TOOLJET_URL -> MARKETPLACE_TOOLJET_URL

* add tests

* refactor: move to plugins.helper for get-service helper utility

* fix; typo

* update package-lock.json

* review changes

* remove a href

* remove bg color + redirect issue due to href

* add test url

* fix crash on search

* remove extra slash

* feat: allow plugin to be installed from github repository

* remove unwanted args from cli command

* add repo attr while save

* feat: add feature toggle for marketplace feature

* fix: make default config as false

* chore: remove hyperlink

* fix: failing build

* chore: update s3 url to point to prod

* fix failing test

* fix test

* fix: test case

* update module from string pkg

* update env

* fix test

* fix test

* add readme file

* Update README.md

Co-authored-by: Akshay Sasidharan <akshaysasidharan93@gmail.com>
2022-10-27 16:59:43 +05:30

80 lines
2.5 KiB
TypeScript

import {
Controller,
Get,
Post,
Body,
Patch,
Param,
Delete,
UseInterceptors,
ClassSerializerInterceptor,
UseGuards,
ForbiddenException,
} from '@nestjs/common';
import { Plugin } from 'src/entities/plugin.entity';
import { PluginsService } from '../services/plugins.service';
import { CreatePluginDto } from '../dto/create-plugin.dto';
import { UpdatePluginDto } from '../dto/update-plugin.dto';
import { decode } from 'js-base64';
import { PluginsAbilityFactory } from 'src/modules/casl/abilities/plugins-ability.factory';
import { JwtAuthGuard } from 'src/modules/auth/jwt-auth.guard';
import { User } from 'src/decorators/user.decorator';
@Controller('plugins')
@UseInterceptors(ClassSerializerInterceptor)
export class PluginsController {
constructor(private readonly pluginsService: PluginsService, private pluginsAbilityFactory: PluginsAbilityFactory) {}
@Post('install')
@UseGuards(JwtAuthGuard)
async install(@User() user, @Body() createPluginDto: CreatePluginDto) {
const ability = await this.pluginsAbilityFactory.pluginActions(user);
if (!ability.can('installPlugin', Plugin)) {
throw new ForbiddenException('You do not have permissions to perform this action');
}
return this.pluginsService.install(createPluginDto);
}
@Get()
@UseGuards(JwtAuthGuard)
async findAll() {
const plugins = await this.pluginsService.findAll();
return plugins.map((plugin) => {
plugin.iconFile.data = plugin.iconFile.data.toString('utf8');
plugin.manifestFile.data = JSON.parse(decode(plugin.manifestFile.data.toString('utf8')));
return plugin;
});
}
@Get(':id')
@UseGuards(JwtAuthGuard)
findOne(@Param('id') id: string) {
return this.pluginsService.findOne(id);
}
@Patch(':id')
@UseGuards(JwtAuthGuard)
async update(@User() user, @Param('id') id: string, @Body() updatePluginDto: UpdatePluginDto) {
const ability = await this.pluginsAbilityFactory.pluginActions(user);
if (!ability.can('updatePlugin', Plugin)) {
throw new ForbiddenException('You do not have permissions to perform this action');
}
return this.pluginsService.update(id, updatePluginDto);
}
@Delete(':id')
@UseGuards(JwtAuthGuard)
async remove(@User() user, @Param('id') id: string) {
const ability = await this.pluginsAbilityFactory.pluginActions(user);
if (!ability.can('deletePlugin', Plugin)) {
throw new ForbiddenException('You do not have permissions to perform this action');
}
return this.pluginsService.remove(id);
}
}