Commit 654e63f8 authored by FORESTIER Fabien's avatar FORESTIER Fabien
Browse files

Upgrade node version to 12.13 using slim docker image + update organization...

Upgrade node version to 12.13 using slim docker image + update organization model and modify post and update functionalities
parent 7004498d
FROM node:8
FROM node:12.13-slim
# Create app directory
WORKDIR /app
......
This diff is collapsed.
......@@ -44,7 +44,7 @@
"rxjs": "^6.2.2",
"serve-favicon": "^2.5.0",
"swagger-stats": "^0.95.7",
"typeorm": "^0.2.7",
"typeorm": "^0.2.20",
"typescript": "^3.0.1",
"uuid": "^3.3.2"
},
......@@ -83,4 +83,4 @@
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}
\ No newline at end of file
}
import { Module, MiddlewareConsumer, RequestMethod } from '@nestjs/common';
import { OrganizationsModule } from './organizations/organizations.module';
import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common';
import { APP_GUARD } from '@nestjs/core';
import { TypeOrmModule } from '@nestjs/typeorm';
import { LinksModule } from './links/links.module';
import { HealthModule } from './health/health.module';
import { AppLogger } from './app-logger';
import { ConfigModule } from './configuration/config.module';
import { APP_GUARD } from '@nestjs/core';
import { GroupsGuard } from './guards/groups.guards';
import { AppLogger } from './app-logger';
import { HealthModule } from './health/health.module';
import { LinksModule } from './links/links.module';
import { VerifyXsrfTokenAndDecodeJWTPayloadMiddleware } from './middlewares/decode-jwt-payload.middleware';
import { OrganizationsModule } from './organizations/organizations.module';
@Module({
imports: [
......
......@@ -8,6 +8,4 @@ export class Link {
@ApiModelProperty()
url: string;
@ApiModelProperty()
organizationId?: string;
}
\ No newline at end of file
import { Entity, PrimaryColumn, Column, ManyToOne, JoinColumn, BeforeInsert } from 'typeorm';
import { IsString, IsOptional } from 'class-validator';
import { Organization } from '../organizations/organization.entity';
import { ApiModelProperty } from '@nestjs/swagger';
import * as uuidv4 from 'uuid/v4';
import { IsOptional, IsString } from 'class-validator';
import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from 'typeorm';
import { Organization } from '../organizations/organization.entity';
@Entity('link')
export class LinkEntity {
@PrimaryColumn('text')
@IsString()
@PrimaryGeneratedColumn()
@ApiModelProperty()
id: string;
id: number;
@IsString()
@IsOptional()
......@@ -26,7 +24,7 @@ export class LinkEntity {
@Column({ nullable: true })
@IsOptional()
@ApiModelProperty()
organizationId: string;
organizationId: number;
@ManyToOne(type => Organization, organization => organization.links, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'organizationId' })
......
import { Controller, Get, Body, Post, Param, Delete, Put, Query, Response } from '@nestjs/common';
import { LinksService } from './links.service';
import { LinkEntity } from './link.entity';
import { ApiUseTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { Link } from './link.dto';
import { Groups } from '../decorators/groups.decorators';
@ApiUseTags('links')
@Controller('links')
export class LinksController {
constructor(
private linksService: LinksService,
) { }
@ApiOperation({ title: 'Get all links' })
@ApiResponse({ status: 200, description: 'Return all links.' })
@Get()
async findAll(@Query() query, @Response() res): Promise<LinkEntity[]> {
const { links, linksCount } = await this.linksService.findAll(query);
res.append('Content-range', linksCount);
res.send(links);
return;
}
@ApiOperation({ title: 'Get one link' })
@Get(':id')
findOne(@Param('id') id: number) {
return this.linksService.findOne(id);
}
@ApiOperation({ title: 'Create one link' })
@ApiResponse({ status: 201, description: 'The record has been successfully created.' })
@ApiResponse({ status: 403, description: 'User does not have sufficient rights.' })
@Post()
@Groups('admin')
async create(@Body() linkDTo: Link) {
return this.linksService.create(linkDTo);
}
@ApiOperation({ title: 'Update one link' })
@ApiResponse({ status: 201, description: 'The record has been successfully updated.' })
@ApiResponse({ status: 403, description: 'User does not have sufficient rights.' })
@Put(':id')
@Groups('admin')
async update(@Param('id') id: number, @Body() link: Link) {
return this.linksService.update(id, link);
}
@ApiOperation({ title: 'Delete one link' })
@ApiResponse({ status: 403, description: 'User does not have sufficient rights.' })
@Delete(':id')
@Groups('admin')
delete(@Param('id') id: number) {
return this.linksService.delete(id);
}
}
import { Module } from '@nestjs/common';
import { LinksController } from './links.controller';
import { LinksService } from './links.service';
import { LinkEntity } from './link.entity';
import { TypeOrmModule } from '@nestjs/typeorm';
import { LinkEntity } from './link.entity';
import { LinksService } from './links.service';
@Module({
imports: [TypeOrmModule.forFeature([LinkEntity])],
controllers: [LinksController],
providers: [LinksService],
})
export class LinksModule {}
export class LinksModule { }
import { Injectable, Logger, InternalServerErrorException, NotFoundException } from '@nestjs/common';
import { LinkEntity, LinksRO } from './link.entity';
import { Injectable, InternalServerErrorException, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Link } from './link.dto';
import { LinkEntity, LinksRO } from './link.entity';
import { LinkRepository } from './link.repository';
import * as uuidv4 from 'uuid/v4';
@Injectable()
export class LinksService {
......@@ -57,75 +55,6 @@ export class LinksService {
}
}
async findOne(id) {
try {
this.logger.log('Entering function', `${LinksService.name} - ${this.findOne.name}`);
return await this.linkRepository.findOne(id).catch((error) => {
this.logger.error(`Error while looking for the link with id ${id}.`, `${error}`, `${LinksService.name} - ${this.findOne.name}`);
throw new InternalServerErrorException({ error, message: 'Error while looking for the link with id ${id}.' });
});
} catch (error) {
throw error;
}
}
async create(link: Link) {
try {
this.logger.log('Entering function', `${LinksService.name} - ${this.create.name}`);
// cf https://github.com/typeorm/typeorm/issues/2924#issuecomment-430265476
const linkEntity = Object.assign(new LinkEntity(), link);
linkEntity.id = uuidv4();
return await this.linkRepository.save(linkEntity).catch((error) => {
this.logger.error(`Error saving the link into the database.`, `${error}`, `${LinksService.name} - ${this.create.name}`);
throw new InternalServerErrorException({ error, message: 'Error saving the link into the database.' });
});
} catch (error) {
throw error;
}
}
async update(id, link: Link) {
try {
this.logger.log('Entering function', `${LinksService.name} - ${this.update.name}`);
const toUpdate = await this.linkRepository.findOne(id).catch((error) => {
this.logger.error(`Error while looking for the link with the id ${id}.`, `${error}`, `${LinksService.name} - ${this.update.name}`);
throw new InternalServerErrorException({ error, message: 'Error while looking for the link.' });
});
const updated = Object.assign(toUpdate, link);
return await this.linkRepository.save(updated).catch((error) => {
this.logger.error(`Error while updating the resource.`, `${error}`, `${LinksService.name} - ${this.update.name}`);
throw new InternalServerErrorException({ error, message: 'Error while updating the link.' });
});
} catch (error) {
throw error;
}
}
async delete(id) {
try {
this.logger.log('Entering function', `${LinksService.name} - ${this.delete.name}`);
const toDelete = await this.linkRepository.findOne(id);
if (!toDelete) {
throw new NotFoundException({ message: 'No link exists with the given id' });
}
return await this.linkRepository.delete(id).catch((error) => {
this.logger.error(`Error while deleting the link with id ${id}.`, `${error}`, `${LinksService.name} - ${this.delete.name}`);
throw new InternalServerErrorException({ error, message: `Error while deleting the link with id ${id}.` });
});
} catch (error) {
throw error;
}
}
async deleteOrphans() {
try {
this.logger.log('Entering function', `${LinksService.name} - ${this.deleteOrphans.name}`);
......
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { ValidationPipe } from '@nestjs/common';
import * as swStats from 'swagger-stats';
import * as favicon from 'serve-favicon';
import * as path from 'path';
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import * as cookieParser from 'cookie-parser';
import * as path from 'path';
import * as favicon from 'serve-favicon';
import * as swStats from 'swagger-stats';
import { AppLogger } from './app-logger';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule, {
......@@ -32,7 +32,7 @@ async function bootstrap() {
// Set endpoint serving the swagger documentation
SwaggerModule.setup('api-doc', app, document);
app.useGlobalPipes(new ValidationPipe());
app.useGlobalPipes(new ValidationPipe({ transform: true, whitelist: true }));
await app.listen(3000);
}
......
import {MigrationInterface, QueryRunner} from "typeorm";
export class MakeIDAutogeneratedAndAddUuidOnOrganization1574756164879 implements MigrationInterface {
name = 'MakeIDAutogeneratedAndAddUuidOnOrganization1574756164879'
public async up(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "organization" ADD "uuid" text NOT NULL`, undefined);
await queryRunner.query(`ALTER TABLE "organization" ADD CONSTRAINT "UQ_59f940b5775a9ccf5c2f094c8af" UNIQUE ("uuid")`, undefined);
await queryRunner.query(`ALTER TABLE "link" DROP CONSTRAINT "FK_afeaa57181e374e281c9a647eda"`, undefined);
await queryRunner.query(`ALTER TABLE "organization" DROP CONSTRAINT "PK_472c1f99a32def1b0abb219cd67"`, undefined);
await queryRunner.query(`ALTER TABLE "organization" DROP COLUMN "id"`, undefined);
await queryRunner.query(`ALTER TABLE "organization" ADD "id" SERIAL NOT NULL`, undefined);
await queryRunner.query(`ALTER TABLE "organization" ADD CONSTRAINT "PK_472c1f99a32def1b0abb219cd67" PRIMARY KEY ("id")`, undefined);
await queryRunner.query(`ALTER TABLE "link" DROP CONSTRAINT "PK_26206fb7186da72fbb9eaa3fac9"`, undefined);
await queryRunner.query(`ALTER TABLE "link" DROP COLUMN "id"`, undefined);
await queryRunner.query(`ALTER TABLE "link" ADD "id" SERIAL NOT NULL`, undefined);
await queryRunner.query(`ALTER TABLE "link" ADD CONSTRAINT "PK_26206fb7186da72fbb9eaa3fac9" PRIMARY KEY ("id")`, undefined);
await queryRunner.query(`ALTER TABLE "link" DROP COLUMN "organizationId"`, undefined);
await queryRunner.query(`ALTER TABLE "link" ADD "organizationId" integer`, undefined);
await queryRunner.query(`ALTER TABLE "link" ADD CONSTRAINT "FK_afeaa57181e374e281c9a647eda" FOREIGN KEY ("organizationId") REFERENCES "organization"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
}
public async down(queryRunner: QueryRunner): Promise<any> {
await queryRunner.query(`ALTER TABLE "link" DROP CONSTRAINT "FK_afeaa57181e374e281c9a647eda"`, undefined);
await queryRunner.query(`ALTER TABLE "link" DROP COLUMN "organizationId"`, undefined);
await queryRunner.query(`ALTER TABLE "link" ADD "organizationId" text`, undefined);
await queryRunner.query(`ALTER TABLE "link" DROP CONSTRAINT "PK_26206fb7186da72fbb9eaa3fac9"`, undefined);
await queryRunner.query(`ALTER TABLE "link" DROP COLUMN "id"`, undefined);
await queryRunner.query(`ALTER TABLE "link" ADD "id" text NOT NULL`, undefined);
await queryRunner.query(`ALTER TABLE "link" ADD CONSTRAINT "PK_26206fb7186da72fbb9eaa3fac9" PRIMARY KEY ("id")`, undefined);
await queryRunner.query(`ALTER TABLE "organization" DROP CONSTRAINT "PK_472c1f99a32def1b0abb219cd67"`, undefined);
await queryRunner.query(`ALTER TABLE "organization" DROP COLUMN "id"`, undefined);
await queryRunner.query(`ALTER TABLE "organization" ADD "id" text NOT NULL`, undefined);
await queryRunner.query(`ALTER TABLE "organization" ADD CONSTRAINT "PK_472c1f99a32def1b0abb219cd67" PRIMARY KEY ("id")`, undefined);
await queryRunner.query(`ALTER TABLE "link" ADD CONSTRAINT "FK_afeaa57181e374e281c9a647eda" FOREIGN KEY ("organizationId") REFERENCES "organization"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, undefined);
await queryRunner.query(`ALTER TABLE "organization" DROP CONSTRAINT "UQ_59f940b5775a9ccf5c2f094c8af"`, undefined);
await queryRunner.query(`ALTER TABLE "organization" DROP COLUMN "uuid"`, undefined);
}
}
import { Organization } from './organization.entity';
import { Link } from '../links/link.dto';
import { ApiModelProperty, ApiModelPropertyOptional } from '@nestjs/swagger';
import { IsString, IsOptional, IsArray, MaxLength, IsBoolean } from 'class-validator';
import { IsArray, IsBoolean, IsOptional, IsString, MaxLength } from 'class-validator';
import { Link } from '../links/link.dto';
import { Organization } from './organization.entity';
export class OrganizationDTO {
@ApiModelPropertyOptional()
@IsOptional()
@IsString()
uuid?: string;
@ApiModelProperty()
@IsString()
@MaxLength(200)
......
import { Entity, PrimaryColumn, Column, OneToMany, Generated, BeforeInsert, BeforeUpdate } from 'typeorm';
import { LinkEntity } from '../links/link.entity';
import { ApiModelProperty } from '@nestjs/swagger';
import { IsBoolean } from 'class-validator';
import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
import { LinkEntity } from '../links/link.entity';
@Entity('organization')
export class Organization {
@PrimaryColumn('text')
@PrimaryGeneratedColumn()
@ApiModelProperty()
id: number;
@Column('text', { unique: true, nullable: false })
@ApiModelProperty()
id: string;
uuid: string;
@Column({ length: 200 })
@ApiModelProperty()
......
import { Controller, Get, Body, Post, Param, Delete, Put, Query, Response, UploadedFile, HttpCode, Req } from '@nestjs/common';
import { OrganizationsService } from './organizations.service';
import { ApiUseTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { Body, Controller, Delete, Get, HttpCode, Param, Post, Put, Query, Req, Response } from '@nestjs/common';
import { ApiOperation, ApiResponse, ApiUseTags } from '@nestjs/swagger';
import { ConfigService } from '../configuration/config.service';
import { Groups } from '../decorators/groups.decorators';
import { LinkEntity } from '../links/link.entity';
import { OrganizationDTO } from './organization.dto';
import { Organization } from './organization.entity';
import { LinkEntity } from '../links/link.entity';
import { Groups } from '../decorators/groups.decorators';
import { ConfigService } from '../configuration/config.service';
import { OrganizationsService } from './organizations.service';
@ApiUseTags('organizations')
@Controller('organizations')
......
import { Injectable, Logger, InternalServerErrorException, NotFoundException, ForbiddenException } from '@nestjs/common';
import { Organization } from './organization.entity';
import { ForbiddenException, Injectable, InternalServerErrorException, Logger, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { LinksService } from '../links/links.service';
import { OrganizationsRO, OrganizationDTO } from './organization.dto';
import { OrganizationRepository } from './organization.repository';
import * as uuidv4 from 'uuid/v4';
import { ConfigService } from '../configuration/config.service';
import { LinksService } from '../links/links.service';
import { OrganizationDTO, OrganizationsRO } from './organization.dto';
import { Organization } from './organization.entity';
import { OrganizationRepository } from './organization.repository';
@Injectable()
export class OrganizationsService {
......@@ -130,13 +130,7 @@ export class OrganizationsService {
// cf https://github.com/typeorm/typeorm/issues/2924#issuecomment-430265476
const organizationEntity = Object.assign(new Organization(), organization);
organizationEntity.id = uuidv4();
organizationEntity.links.forEach((link) => {
if (!link.id) {
link.id = uuidv4();
}
});
organizationEntity.uuid = organizationEntity.uuid ? organizationEntity.uuid : uuidv4();
const organizationCreated = await this.organizationRepository.save(organizationEntity).catch((error) => {
this.logger.error(`Error saving the organization into the database.`, `${error}`, `${OrganizationsService.name} - ${this.create.name}`);
......@@ -171,11 +165,6 @@ export class OrganizationsService {
}
const updated = Object.assign(toUpdate, organization);
updated.links.forEach((link) => {
if (!link.id) {
link.id = uuidv4();
}
});
const saved = await this.organizationRepository.save(updated).catch((error) => {
this.logger.error(`Error while updating the organization.`, `${error}`, `${OrganizationsService.name} - ${this.update.name}`);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment