ToolJet/server/src/controllers/organizations.controller.ts
Muhsin Shah C P 3ea8d6e3ca
[feature] Make workspace urls more readable (#6698)
* working on replacing workspace id with workspace name

* experimenting with zustand

* added slug column to workspace table

* working on workspace url

* working on backward compatibility

* fixing bugs

* added not found error

* fixed workspace switching issue

* fix: switching b/w workspaces

* fix: workspace login

* changed workspace login url link

* resolved conflicts

* added create organization design

* added backend validation

* fixed constraint errors issue

* fixed: creating new workspace

* fixed: update workspace

* fixed: update workspace bugs

* fixed: auto created slug bugs

* fixed: login slug

* design changes

* added folder slug

* fixed: lint error

* fixed: invite and first user issues

* fixed: login page redirection

* fixed: redirect path

* added reserved word check

* fix: edit workspace design

* fix: folder query issue

* fix: create and edit workspace modal validation issues

* fixing failed test cases

* fixing failed test cases - app.e2e

* fixed organizations specs

* fixed public app issue

* working on app slug

* Added app slug design to the general settings

* Working on appId -> slug changes
- Handling appId cases
- Fixing issues

* Worked on share modal design change
- replaced slug functionality
- Fixed backend slug issues
- Fixed page handle issues

* changed switch label

* replace version param with query param

* fix: possible uuid bug

* fix: login app slug redirection issue

* Worked on unique app slug

* moved all apps related api calls to apps.service.js file

* refactoring the code and fixing minor issues

* Refactored and fixed some bugs

* Fixed bugs: redirect cookie issue

* Fixed dark-mode issues

* removed duplicate code

* Worked on develop branch conflicts

* Moved handle app access check to private route

* Added fix for navigate

* Refactored the code. Added slug to failed sso login redirection path

* again some redirect url fixes

* onbaord navbar tj-icon onclick

* Fix: viewer version id undefined issue

* fix: multi-pages, invalid workspace slug

* fix: removing the version search param while switching the pages

* fix-sso: redirecting to prev tab's login organization slug

* fix-sso: google signup

* fix: preivew permission issue

* Fixing merge issues

* Fixed tjdb issues

* dark mode fix of manage users button

* fix: extra slash in url, tj-logo on click wrong org id

* subpath workspace login url

* resolved lint issue

* fix: cannot clone apps

* fixed switch workspace issue

* fix: login page flashing issue

* fix: back button issue

* fix: private endless redirection

* Update the modal with new UX

* fixed all ui issues

* fixed placeholder translation issues

* fix: sso multi-request issues

* fix: multi-pages crash while promoting a version

* fix: error text msg delay

* added default slug to the first workspace in the instance

* subpath-fix: slug preview url

* fix: same value check

* fixed switch page query params issue

* fix: folder query

* fix: manage app users ui responsive issue

* Backend PR changes

---------

Co-authored-by: gsmithun4 <gsmithun4@gmail.com>
2023-10-18 13:00:17 +05:30

127 lines
4.7 KiB
TypeScript

import { Body, Controller, Get, NotFoundException, Param, Patch, Post, UseGuards, Query, Res } from '@nestjs/common';
import { OrganizationsService } from '@services/organizations.service';
import { decamelizeKeys } from 'humps';
import { User } from 'src/decorators/user.decorator';
import { JwtAuthGuard } from '../../src/modules/auth/jwt-auth.guard';
import { AuthService } from '@services/auth.service';
import { AppAbility } from 'src/modules/casl/casl-ability.factory';
import { CheckPolicies } from 'src/modules/casl/check_policies.decorator';
import { PoliciesGuard } from 'src/modules/casl/policies.guard';
import { User as UserEntity } from 'src/entities/user.entity';
import { OrganizationCreateDto, OrganizationUpdateDto } from '@dto/organization.dto';
import { Response } from 'express';
@Controller('organizations')
export class OrganizationsController {
constructor(private organizationsService: OrganizationsService, private authService: AuthService) {}
@UseGuards(JwtAuthGuard, PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can('viewAllUsers', UserEntity))
@Get('users')
async getUsers(@User() user, @Query() query) {
const { page, searchText, status } = query;
const filterOptions = {
...(searchText && { searchText }),
...(status && { status }),
};
const usersCount = await this.organizationsService.usersCount(user, filterOptions);
let users = [];
if (usersCount > 0) users = await this.organizationsService.fetchUsers(user, page, filterOptions);
const meta = {
total_pages: Math.ceil(usersCount / 10),
total_count: usersCount,
current_page: parseInt(page || 1),
};
const response = {
meta,
users,
};
return decamelizeKeys(response);
}
@UseGuards(JwtAuthGuard)
@Get('users/suggest')
async getUserSuggestions(@User() user, @Query('input') searchInput) {
const users = await this.organizationsService.fetchUsersByValue(user, searchInput);
const response = {
users,
};
return decamelizeKeys(response);
}
@UseGuards(JwtAuthGuard)
@Get()
async get(@User() user) {
const result = await this.organizationsService.fetchOrganizations(user);
return decamelizeKeys({ organizations: result });
}
@UseGuards(JwtAuthGuard)
@Post()
async create(
@User() user,
@Body() organizationCreateDto: OrganizationCreateDto,
@Res({ passthrough: true }) response: Response
) {
const result = await this.organizationsService.create(organizationCreateDto.name, organizationCreateDto.slug, user);
if (!result) {
throw new Error();
}
return await this.authService.switchOrganization(response, result.id, user, true);
}
@Get(['/:organizationId/public-configs', '/public-configs'])
async getOrganizationDetails(@Param('organizationId') organizationId: string) {
const existingOrganizationId = (await this.organizationsService.getSingleOrganization())?.id;
if (!existingOrganizationId) {
throw new NotFoundException();
}
if (!organizationId) {
const result = this.organizationsService.constructSSOConfigs();
return decamelizeKeys({ ssoConfigs: result });
}
const result = await this.organizationsService.fetchOrganizationDetails(organizationId, [true], true, true);
if (!result) throw new NotFoundException();
return decamelizeKeys({ ssoConfigs: result });
}
@UseGuards(JwtAuthGuard, PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can('updateOrganizations', UserEntity))
@Get('/configs')
async getConfigs(@User() user) {
const result = await this.organizationsService.fetchOrganizationDetails(user.organizationId);
return decamelizeKeys({
organizationDetails: result,
instanceConfigs: this.organizationsService.constructSSOConfigs(),
});
}
@UseGuards(JwtAuthGuard, PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can('updateOrganizations', UserEntity))
@Patch()
async update(@Body() organizationUpdateDto: OrganizationUpdateDto, @User() user) {
await this.organizationsService.updateOrganization(user.organizationId, organizationUpdateDto);
return;
}
@UseGuards(JwtAuthGuard, PoliciesGuard)
@CheckPolicies((ability: AppAbility) => ability.can('updateOrganizations', UserEntity))
@Patch('/configs')
async updateConfigs(@Body() body, @User() user) {
const result: any = await this.organizationsService.updateOrganizationConfigs(user.organizationId, body);
return decamelizeKeys({ id: result.id });
}
@UseGuards(JwtAuthGuard)
@Get('/is-unique')
async checkWorkspaceUnique(@User() user, @Query('name') name: string, @Query('slug') slug: string) {
return this.organizationsService.checkWorkspaceUniqueness(name, slug);
}
}