Compare commits
6 Commits
2f0c2f8b7c
...
4547a22f5c
Author | SHA1 | Date | |
---|---|---|---|
4547a22f5c | |||
1020d6283d | |||
0330358139 | |||
38634132ba | |||
7b4792b612 | |||
989ec71e2e |
@ -1,8 +1,10 @@
|
||||
import { Controller, Get } from "@nestjs/common";
|
||||
|
||||
import { AppService } from "./app.service";
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
|
||||
@Controller()
|
||||
@ApiTags("useless")
|
||||
export class AppController {
|
||||
constructor(private readonly appService: AppService) {}
|
||||
|
||||
|
@ -13,7 +13,9 @@ import {
|
||||
import { SignInDto, SignUpDto } from "apps/backend/src/app/auth/auth.dto";
|
||||
import { AuthService } from "apps/backend/src/app/auth/auth.service";
|
||||
import { UserGuard } from "./auth.guard";
|
||||
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||
|
||||
@ApiTags('User authentification')
|
||||
@Controller("auth")
|
||||
export class AuthController {
|
||||
constructor(private readonly authService: AuthService) {}
|
||||
@ -33,6 +35,7 @@ export class AuthController {
|
||||
return this.authService.doLogin(dto);
|
||||
}
|
||||
//GET me -- Get current user data via jwt
|
||||
@ApiBearerAuth()
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@Get("me")
|
||||
@UseGuards(UserGuard)
|
||||
@ -46,6 +49,7 @@ export class AuthController {
|
||||
return userData;
|
||||
}
|
||||
//DELETE me
|
||||
@ApiBearerAuth()
|
||||
@HttpCode(HttpStatus.FOUND)
|
||||
@Delete("me")
|
||||
@UseGuards(UserGuard)
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
MaxLength,
|
||||
MinLength,
|
||||
} from "class-validator";
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class SignUpDto {
|
||||
/*
|
||||
@ -22,11 +23,17 @@ export class SignUpDto {
|
||||
lastName: string;
|
||||
**/
|
||||
|
||||
@ApiProperty({
|
||||
example: 'jean@paul.fr',
|
||||
})
|
||||
@MaxLength(32)
|
||||
@IsEmail()
|
||||
@IsNotEmpty()
|
||||
email: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: 'zSEs-6ze$',
|
||||
})
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
@IsStrongPassword({
|
||||
@ -36,12 +43,16 @@ export class SignUpDto {
|
||||
}
|
||||
|
||||
export class SignInDto {
|
||||
@MaxLength(32)
|
||||
@MaxLength(32)@ApiProperty({
|
||||
example: 'jean@paul.fr',
|
||||
})
|
||||
@IsEmail()
|
||||
@IsNotEmpty()
|
||||
email: string;
|
||||
|
||||
@IsString()
|
||||
@IsString()@ApiProperty({
|
||||
example: 'zSEs-6ze$',
|
||||
})
|
||||
@IsNotEmpty()
|
||||
@IsStrongPassword({
|
||||
minLength: 6,
|
||||
|
@ -11,7 +11,9 @@ import {
|
||||
} from "@nestjs/common";
|
||||
import { AdminGuard } from "apps/backend/src/app/auth/auth.guard";
|
||||
import { AuthorsService } from "apps/backend/src/app/authors/authors.service";
|
||||
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||
|
||||
@ApiTags('File authors')
|
||||
@Controller("authors")
|
||||
export class AuthorsController {
|
||||
constructor(private readonly authorService: AuthorsService) {}
|
||||
@ -25,8 +27,8 @@ export class AuthorsController {
|
||||
return await this.authorService.find(limit, offset, search);
|
||||
}
|
||||
|
||||
//TODO DTO
|
||||
|
||||
//TODO Refactor
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(AdminGuard)
|
||||
@Delete(":autor")
|
||||
async deleteAuthor(@Param("author") author: string) {
|
||||
|
@ -103,7 +103,7 @@ export const FilesTable = pgTable("files", {
|
||||
})
|
||||
.notNull(),
|
||||
});
|
||||
export type IFileTable = typeof FilesTable.$inferSelect
|
||||
export type IFileTable = typeof FilesTable.$inferSelect;
|
||||
|
||||
export const FilesGroupTable = pgTable("f_groups", {
|
||||
uuid: p.uuid("uuid").unique().primaryKey().defaultRandom().notNull(),
|
||||
@ -115,8 +115,7 @@ export const FilesGroupTable = pgTable("f_groups", {
|
||||
.unique()
|
||||
.notNull(),
|
||||
});
|
||||
export type IFileGroupTable = typeof FilesGroupTable.$inferSelect
|
||||
|
||||
export type IFileGroupTable = typeof FilesGroupTable.$inferSelect;
|
||||
|
||||
//TODO Files types
|
||||
export const FilesTypesTable = pgTable("f_types", {
|
||||
@ -137,7 +136,7 @@ export const FilesTypesTable = pgTable("f_types", {
|
||||
.unique()
|
||||
.notNull(),
|
||||
});
|
||||
export type IFilesTypesTable = typeof FilesTypesTable.$inferSelect
|
||||
export type IFilesTypesTable = typeof FilesTypesTable.$inferSelect;
|
||||
|
||||
export const MachinesTable = pgTable("machines", {
|
||||
id: p.uuid("id").unique().primaryKey().defaultRandom().notNull(),
|
||||
@ -156,7 +155,7 @@ export const MachinesTable = pgTable("machines", {
|
||||
|
||||
//supported files format
|
||||
});
|
||||
export type IMachinesTable = typeof MachinesTable.$inferSelect
|
||||
export type IMachinesTable = typeof MachinesTable.$inferSelect;
|
||||
|
||||
//TODO Many to Many table betwen File en Machine
|
||||
export const FilesForMachinesTable = pgTable("files_for_machines", {
|
||||
@ -172,7 +171,7 @@ export const FilesForMachinesTable = pgTable("files_for_machines", {
|
||||
.notNull()
|
||||
.references(() => MachinesTable.id),
|
||||
});
|
||||
export type IFilesForMachinesTable = typeof FilesForMachinesTable.$inferSelect
|
||||
export type IFilesForMachinesTable = typeof FilesForMachinesTable.$inferSelect;
|
||||
|
||||
export const FilesTypeForMachine = pgTable("f_type_for_machines", {
|
||||
id: p.uuid("id").unique().primaryKey().defaultRandom().notNull(),
|
||||
@ -186,11 +185,11 @@ export const FilesTypeForMachine = pgTable("f_type_for_machines", {
|
||||
.notNull()
|
||||
.references(() => FilesTypesTable.id),
|
||||
});
|
||||
export type IFilesTypeForMachine = typeof FilesTypeForMachine.$inferSelect
|
||||
export type IFilesTypeForMachine = typeof FilesTypeForMachine.$inferSelect;
|
||||
|
||||
export interface IWithCount<T> {
|
||||
count: number;
|
||||
limit: number;
|
||||
currentOffset: number;
|
||||
data: T
|
||||
data: T[];
|
||||
}
|
@ -23,7 +23,9 @@ import {
|
||||
import { CreateFileTypeDto } from "apps/backend/src/app/files/files.dto";
|
||||
import { AdminGuard, InsertAdminState } from "../auth/auth.guard";
|
||||
import { FilesService } from "./files.service";
|
||||
import { ApiBearerAuth, ApiSecurity, ApiTags } from '@nestjs/swagger';
|
||||
|
||||
@ApiTags('Files')
|
||||
@Controller("files")
|
||||
export class FilesController {
|
||||
constructor(private readonly filesService: FilesService) {}
|
||||
@ -129,6 +131,7 @@ export class FilesController {
|
||||
return await this.filesService.getAllFilesTypes();
|
||||
}
|
||||
|
||||
@ApiBearerAuth()
|
||||
@HttpCode(HttpStatus.CREATED)
|
||||
@UseGuards(AdminGuard)
|
||||
@Post("types/new")
|
||||
@ -136,6 +139,7 @@ export class FilesController {
|
||||
return await this.filesService.createFileType(body.name, body.mime);
|
||||
}
|
||||
|
||||
@ApiBearerAuth()
|
||||
@HttpCode(HttpStatus.ACCEPTED)
|
||||
@UseGuards(AdminGuard)
|
||||
@Delete("types/:typeId")
|
||||
@ -149,6 +153,7 @@ export class FilesController {
|
||||
return await this.filesService.get(fileId);
|
||||
}
|
||||
|
||||
@ApiBearerAuth()
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@UseGuards(AdminGuard)
|
||||
@Delete(":fileId")
|
||||
|
@ -1,27 +1,26 @@
|
||||
import { DefaultValuePipe } from "@nestjs/common";
|
||||
import { IsUUID, MaxLength, MinLength } from "class-validator";
|
||||
|
||||
export class CreateFilesDto {
|
||||
@MaxLength(128)
|
||||
@MinLength(4)
|
||||
fileName: string;
|
||||
|
||||
@MaxLength(64)
|
||||
@MinLength(2)
|
||||
uploadedBy: string;
|
||||
|
||||
isDocumentation?: boolean;
|
||||
isRestricted?: boolean;
|
||||
|
||||
@IsUUID()
|
||||
groupId: string;
|
||||
}
|
||||
import { ApiBearerAuth, ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class CreateFileTypeDto {
|
||||
@ApiProperty({
|
||||
description: "Admin uniquement, nom d'affichage.",
|
||||
examples: [
|
||||
".scad",
|
||||
"jpg"
|
||||
]
|
||||
})
|
||||
@MaxLength(128)
|
||||
@MinLength(3)
|
||||
name: string;
|
||||
|
||||
@ApiProperty({
|
||||
description: "Admin uniquement, Multipurpose Internet Mail Extensions (MIME)",
|
||||
examples: [
|
||||
"application/x-openscad",
|
||||
"image/jpeg"
|
||||
]
|
||||
})
|
||||
@MaxLength(64)
|
||||
@MinLength(4)
|
||||
mime: string;
|
||||
|
@ -12,10 +12,12 @@ import {
|
||||
FilesTable,
|
||||
FilesTypeForMachine,
|
||||
FilesTypesTable,
|
||||
IFileTable,
|
||||
IWithCount,
|
||||
MachinesTable,
|
||||
} from "apps/backend/src/app/db/schema";
|
||||
import { StorageService } from "apps/backend/src/app/storage/storage.service";
|
||||
import { eq, ilike } from "drizzle-orm";
|
||||
import { count, eq, ilike } from "drizzle-orm";
|
||||
|
||||
@Injectable()
|
||||
export class FilesService {
|
||||
@ -124,17 +126,27 @@ export class FilesService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for files in the database using the specified search field, limit, and offset.
|
||||
* Searches for files in the database based on the provided search field, limit, and offset.
|
||||
*
|
||||
* @param {number} limit - The maximum number of results to return.
|
||||
* @param {number} offset - The number of results to skip before starting to return results.
|
||||
* @param {string} searchField - The field used to search for matching file names.
|
||||
*
|
||||
* @return {Promise<object>} A promise that resolves to the search results.
|
||||
* @param {number} offset - The offset for the results.
|
||||
* @param {string} searchField - The value to search for within the file names.
|
||||
* @return {Promise<IWithCount<IFileTable>>} A promise that resolves to an object containing the count of files that match the search criteria, the provided limit, the current offset, and the matching data.
|
||||
*/
|
||||
public async search(limit: number, offset: number, searchField: string) {
|
||||
public async search(
|
||||
limit: number,
|
||||
offset: number,
|
||||
searchField: string,
|
||||
): Promise<IWithCount<IFileTable>> {
|
||||
try {
|
||||
return await this.database
|
||||
const countResult = await this.database
|
||||
.use()
|
||||
.select({ count: count() })
|
||||
.from(FilesTable)
|
||||
.where(ilike(FilesTable.fileName, String(`%${searchField}%`)))
|
||||
.prepare("searchFilesCount")
|
||||
.execute();
|
||||
const dataResult = await this.database
|
||||
.use()
|
||||
.select()
|
||||
.from(FilesTable)
|
||||
@ -143,6 +155,12 @@ export class FilesService {
|
||||
.offset(offset)
|
||||
.prepare("searchFiles")
|
||||
.execute();
|
||||
return {
|
||||
count: countResult[0].count,
|
||||
limit: limit,
|
||||
currentOffset: offset,
|
||||
data: dataResult,
|
||||
};
|
||||
} catch (error) {
|
||||
throw new InternalServerErrorException(error);
|
||||
}
|
||||
|
@ -14,7 +14,9 @@ import { AdminGuard } from "apps/backend/src/app/auth/auth.guard";
|
||||
import { CreateGroupDto } from "apps/backend/src/app/groups/groups.dto";
|
||||
import { ISearchQuery } from "apps/backend/src/app/groups/groups.types";
|
||||
import { GroupsService } from "./groups.service";
|
||||
import { ApiBearerAuth, ApiTags } from '@nestjs/swagger';
|
||||
|
||||
@ApiTags('File groups')
|
||||
@Controller("groups")
|
||||
export class GroupsController {
|
||||
constructor(private readonly groupsService: GroupsService) {}
|
||||
@ -33,6 +35,7 @@ export class GroupsController {
|
||||
return await this.groupsService.newGroup(body.groupName);
|
||||
}
|
||||
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(AdminGuard)
|
||||
@Delete(":groupId")
|
||||
async deleteGroup(@Param("groupId") groupId: string) {
|
||||
|
@ -1,6 +1,11 @@
|
||||
import { IsString, MaxLength, MinLength } from "class-validator";
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class CreateGroupDto {
|
||||
@ApiProperty({
|
||||
description: "Nom unique.",
|
||||
example: "Numérique en communs"
|
||||
})
|
||||
@IsString()
|
||||
@MinLength(4)
|
||||
@MaxLength(64)
|
||||
|
@ -19,7 +19,9 @@ import {
|
||||
TypeDto,
|
||||
} from "apps/backend/src/app/machines/machines.dto";
|
||||
import { MachinesService } from "apps/backend/src/app/machines/machines.service";
|
||||
import { ApiTags } from '@nestjs/swagger';
|
||||
|
||||
@ApiTags('Machines')
|
||||
@Controller("machines")
|
||||
export class MachinesController {
|
||||
constructor(private readonly machineService: MachinesService) {}
|
||||
|
@ -1,16 +1,27 @@
|
||||
import { IsUUID, MaxLength, MinLength } from "class-validator";
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
export class CreateMachineDto {
|
||||
@ApiProperty({
|
||||
example: "Découpeuse laser portable"
|
||||
})
|
||||
@MaxLength(128)
|
||||
@MinLength(4)
|
||||
machineName: string;
|
||||
|
||||
@ApiProperty({
|
||||
example: "Découpe au laser"
|
||||
})
|
||||
@MaxLength(64)
|
||||
@MinLength(2)
|
||||
machineType: string;
|
||||
}
|
||||
|
||||
export class TypeDto {
|
||||
@ApiProperty({
|
||||
description: "Un identifiant unique présent en base de donnée qui représente un MIME",
|
||||
example: "dfd0fbb1-2bf3-4dbe-b86d-89b1bff5106c"
|
||||
})
|
||||
@IsUUID()
|
||||
fileTypeId: string;
|
||||
}
|
||||
|
@ -10,6 +10,11 @@ async function bootstrap() {
|
||||
.setTitle("Fab Explorer")
|
||||
.setDescription("Définition de l'api du FabLab Explorer")
|
||||
.setVersion("1.0")
|
||||
.addBearerAuth({
|
||||
type: 'http',
|
||||
scheme: 'bearer',
|
||||
in: 'header',
|
||||
})
|
||||
.build();
|
||||
|
||||
const app = await NestFactory.create(AppModule);
|
||||
|
Loading…
x
Reference in New Issue
Block a user