All files / libs/tenants/companies/core/src/lib companies.controller.ts

92.38% Statements 97/105
37.5% Branches 9/24
83.33% Functions 5/6
92.38% Lines 97/105

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 1061x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 4x 4x 4x 1x 1x 1x 5x 5x 1x 1x 1x 1x 3x 3x 3x 3x 3x 2x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 4x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x                 1x  
import { Body, Controller, Get, Inject, Patch, Post, Put, UseGuards } from '@nestjs/common';
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
import { pick } from 'lodash-es';
 
import { Company, User } from '@amalia/core/models';
import {
  AmaliaAuthGuard,
  CheckPolicies,
  CurrentAuthenticatedContext,
  CurrentUser,
  CurrentUserCompany,
  PoliciesGuard,
  SuperAdminAuthGuard,
} from '@amalia/kernel/auth/core';
import { canCreateCompany, canModifyCompanySettings } from '@amalia/kernel/auth/shared';
import { type AuthenticatedContext } from '@amalia/kernel/auth/types';
import { toCompanyResponseDto } from '@amalia/tenants/companies/api';
import { type Company as CompanyType } from '@amalia/tenants/companies/types';
 
import { CompaniesService } from './companies.service';
import { CompaniesIntegrationsService } from './companiesIntegrations/companiesIntegrations.service';
import { CompanyIntegrationDto } from './dto/companyIntegration.dto';
import { CreateCompanyDto } from './dto/createCompany.dto';
import { UpdateCompanyDto } from './dto/updateCompany.dto';
import { UploadLogoDto } from './dto/uploadLogo.dto';
import { UpdateLogoUseCase } from './use-cases/update-logo.use-case';
 
@ApiTags('companies')
@Controller('companies')
@UseGuards(AmaliaAuthGuard, PoliciesGuard)
@ApiBearerAuth()
export class CompaniesController {
  public constructor(
    @Inject(CompaniesService)
    private readonly companyService: CompaniesService,
    @Inject(CompaniesIntegrationsService)
    private readonly companyIntegrationService: CompaniesIntegrationsService,
    private readonly updateLogoUseCase: UpdateLogoUseCase,
  ) {}
 
  @Get()
  public async findOne(@CurrentUser() user: User): Promise<CompanyType> {
    return toCompanyResponseDto(await this.companyService.findById(user.company.id));
  }
 
  @Patch()
  @CheckPolicies((ability) => canModifyCompanySettings(ability))
  public async update(
    @Body() company: UpdateCompanyDto,
    @CurrentUserCompany() companyDecorator: Company,
    @CurrentAuthenticatedContext() authenticatedContext: AuthenticatedContext,
  ): Promise<CompanyType> {
    return toCompanyResponseDto(await this.companyService.update(companyDecorator, company, authenticatedContext));
  }
 
  /**
   * Creates a new company with a new admin (empty or with sample data).
   *
   * This endpoint uses a different guard system because you don't necessarily have an Amalia account
   * when you create a company, for instance when a tech bootstraps the project or when Cypress runs the suite.
   *
   * No account means that there is no "real" user that we can run the PoliciesGuard on, and can lead to other
   * crashes and error. So we use another guard that just checks if the JWT is valid and if the current user
   * has an `*@amalia.io` mail address, see the code of SuperAdminGuard for more details.
   *
   * @param createCompanyDto
   */
  @Post()
  @UseGuards(SuperAdminAuthGuard)
  @CheckPolicies(canCreateCompany)
  public async create(@Body() createCompanyDto: CreateCompanyDto): Promise<CompanyType> {
    return toCompanyResponseDto(await this.companyService.create(createCompanyDto));
  }
 
  @Put('integration')
  @CheckPolicies((ability) => canModifyCompanySettings(ability))
  public async updateIntegration(
    @CurrentUserCompany() company: Company,
    @Body() companyIntegration: CompanyIntegrationDto,
  ): Promise<void> {
    await this.companyIntegrationService.updateCompanyIntegration(
      company.id,
      pick(companyIntegration, 'name', 'credentials'),
    );
  }
 
  /**
   * @description Update the logo.
   *
   * @param authenticatedContext
   * @param body
   */
  @Patch('logo')
  @UseGuards(AmaliaAuthGuard, PoliciesGuard)
  @CheckPolicies((ability) => canModifyCompanySettings(ability))
  public async updateLogo(
    @CurrentAuthenticatedContext() authenticatedContext: AuthenticatedContext,
    @Body() body: UploadLogoDto,
  ): Promise<Required<User>['pictureURL']> {
    return this.updateLogoUseCase.execute({
      authenticatedContext,
      updateLogo: body,
    });
  }
}