Refactor and log changes in storage and file services
Convert array of machine IDs to sets for uniqueness in methods. Add console logs for debugging and update error handling to improve clarity. Refactor the files controller for better readability.
This commit is contained in:
parent
ff649ebdbf
commit
6f9d25a58b
@ -1,24 +1,24 @@
|
||||
import { IncomingMessage } from "node:http";
|
||||
import {
|
||||
BadRequestException,
|
||||
Body,
|
||||
Controller,
|
||||
DefaultValuePipe,
|
||||
Delete,
|
||||
Get,
|
||||
HttpCode,
|
||||
HttpStatus,
|
||||
Param,
|
||||
ParseIntPipe,
|
||||
ParseUUIDPipe,
|
||||
Post,
|
||||
Query,
|
||||
Req,
|
||||
Request,
|
||||
Res,
|
||||
Response,
|
||||
StreamableFile,
|
||||
UseGuards,
|
||||
BadRequestException,
|
||||
Body,
|
||||
Controller,
|
||||
DefaultValuePipe,
|
||||
Delete,
|
||||
Get,
|
||||
HttpCode,
|
||||
HttpStatus,
|
||||
Param,
|
||||
ParseIntPipe,
|
||||
ParseUUIDPipe,
|
||||
Post,
|
||||
Query,
|
||||
Req,
|
||||
Request,
|
||||
Res,
|
||||
Response,
|
||||
StreamableFile,
|
||||
UseGuards,
|
||||
} from "@nestjs/common";
|
||||
import { CreateFileTypeDto } from "apps/backend/src/app/files/files.dto";
|
||||
import { AdminGuard, InsertAdminState } from "../auth/auth.guard";
|
||||
@ -26,132 +26,133 @@ import { FilesService } from "./files.service";
|
||||
|
||||
@Controller("files")
|
||||
export class FilesController {
|
||||
constructor(private readonly filesService: FilesService) { }
|
||||
constructor(private readonly filesService: FilesService) {}
|
||||
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@UseGuards(InsertAdminState)
|
||||
@Post("new")
|
||||
async saveFile(@Req() req: IncomingMessage, @Res() res: Response) {
|
||||
let fileBuffer: Buffer = Buffer.from([]);
|
||||
req.on("data", (chunk: Buffer) => {
|
||||
fileBuffer = Buffer.concat([fileBuffer, chunk]);
|
||||
});
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@UseGuards(InsertAdminState)
|
||||
@Post("new")
|
||||
async saveFile(@Req() req: IncomingMessage, @Res() res: Response) {
|
||||
let fileBuffer: Buffer = Buffer.from([]);
|
||||
req.on("data", (chunk: Buffer) => {
|
||||
fileBuffer = Buffer.concat([fileBuffer, chunk]);
|
||||
});
|
||||
|
||||
req.on("end", async () => {
|
||||
try {
|
||||
console.log(fileBuffer);
|
||||
const _fileName = req.headers["file_name"] as string;
|
||||
const _groupId = req.headers["group_id"] as string;
|
||||
const _uploadedBy = req.headers["uploaded_by"] as string;
|
||||
const _machineId = req.headers["machine_id"];
|
||||
const _isDocumentation = req.headers["is_documentation"] as string;
|
||||
const _isRestricted = req.headers["is_restricted"] as string;
|
||||
const _isAdmin = Boolean(req.headers["is_admin"] as string | boolean);
|
||||
console.log(
|
||||
_fileName,
|
||||
_groupId,
|
||||
_uploadedBy,
|
||||
_machineId,
|
||||
_isDocumentation,
|
||||
_isRestricted,
|
||||
_isAdmin,
|
||||
);
|
||||
req.on("end", async () => {
|
||||
try {
|
||||
console.log(fileBuffer);
|
||||
const _fileName = req.headers["file_name"] as string;
|
||||
const _groupId = req.headers["group_id"] as string;
|
||||
const _uploadedBy = req.headers["uploaded_by"] as string;
|
||||
const _machineId = req.headers["machine_id"];
|
||||
const _isDocumentation = req.headers["is_documentation"] as string;
|
||||
const _isRestricted = req.headers["is_restricted"] as string;
|
||||
const _isAdmin = Boolean(req.headers["is_admin"] as string | boolean);
|
||||
console.log(
|
||||
_fileName,
|
||||
_groupId,
|
||||
_uploadedBy,
|
||||
_machineId,
|
||||
_isDocumentation,
|
||||
_isRestricted,
|
||||
_isAdmin,
|
||||
);
|
||||
|
||||
// Vérifier que les en-têtes nécessaires sont présents
|
||||
if (!_fileName || !_machineId) {
|
||||
throw new BadRequestException("Header(s) manquant(s)");
|
||||
}
|
||||
console.log("Header found !");
|
||||
const machineId = Array(_machineId);
|
||||
// Vérifier que les en-têtes nécessaires sont présents
|
||||
if (!_fileName || !_machineId || !_uploadedBy) {
|
||||
throw new BadRequestException("Header(s) manquant(s)");
|
||||
}
|
||||
console.log("Header found !");
|
||||
const machineId = Array(_machineId);
|
||||
|
||||
const Params = new Map()
|
||||
.set("fileName", _fileName.toString())
|
||||
.set("groupId", _groupId.toString() || null)
|
||||
.set("uploadedBy", _uploadedBy.toString())
|
||||
.set("machineId", Array(JSON.parse(machineId.toString())))
|
||||
.set("isDocumentation", false)
|
||||
.set("isRestricted", false);
|
||||
const Params = new Map()
|
||||
.set("groupId", null)
|
||||
.set("fileName", _fileName.toString())
|
||||
.set("uploadedBy", String(_uploadedBy))
|
||||
.set("machineId", Array(machineId))
|
||||
.set("isDocumentation", false)
|
||||
.set("isRestricted", false);
|
||||
|
||||
console.log("Current params :\n", Params);
|
||||
if (_groupId) Params.set("groupId", String(_groupId));
|
||||
|
||||
//TODO Integrate a verification if the source is an admin, if that the case then it can define isDocumentation and isRestricted else throw in case of presence of those parameters.
|
||||
if (_isAdmin) {
|
||||
Params.set("isDocumentation", Boolean(_isDocumentation));
|
||||
Params.set("isRestricted", Boolean(_isRestricted));
|
||||
}
|
||||
console.log("Current params :\n", Params);
|
||||
|
||||
console.log("Executing save procedure...");
|
||||
return (
|
||||
res
|
||||
// @ts-ignore
|
||||
.status(HttpStatus.CREATED)
|
||||
.send(await this.filesService.save(fileBuffer, Params))
|
||||
);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return (
|
||||
res
|
||||
// @ts-ignore
|
||||
.status(err.status || HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
.send(err)
|
||||
);
|
||||
}
|
||||
});
|
||||
//TODO Integrate a verification if the source is an admin, if that the case then it can define isDocumentation and isRestricted else throw in case of presence of those parameters.
|
||||
if (_isAdmin) {
|
||||
Params.set("isDocumentation", Boolean(_isDocumentation));
|
||||
Params.set("isRestricted", Boolean(_isRestricted));
|
||||
}
|
||||
|
||||
req.on("error", (err) => {
|
||||
return (
|
||||
res
|
||||
// @ts-ignore
|
||||
.status(err.status || HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
.send(err)
|
||||
);
|
||||
});
|
||||
console.log("Executing save procedure...");
|
||||
return (
|
||||
res
|
||||
// @ts-ignore
|
||||
.status(HttpStatus.CREATED)
|
||||
.send(await this.filesService.save(fileBuffer, Params))
|
||||
);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return (
|
||||
res
|
||||
// @ts-ignore
|
||||
.status(err.status || HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
.send(err)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
req.on("error", (err) => {
|
||||
return (
|
||||
res
|
||||
// @ts-ignore
|
||||
.status(err.status || HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
.send(err)
|
||||
);
|
||||
});
|
||||
|
||||
@HttpCode(HttpStatus.FOUND)
|
||||
@Get("find")
|
||||
async findMany(
|
||||
@Query("limit", new DefaultValuePipe(20), ParseIntPipe) limit: number,
|
||||
@Query("offset", new DefaultValuePipe(0), ParseIntPipe) offset: number,
|
||||
@Query("search", new DefaultValuePipe("")) search: string,
|
||||
) {
|
||||
return this.filesService.search(limit, offset, search);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@HttpCode(HttpStatus.FOUND)
|
||||
@Get("types")
|
||||
async getTypes() {
|
||||
console.log("Performing request")
|
||||
return await this.filesService.getAllFilesTypes();
|
||||
}
|
||||
@HttpCode(HttpStatus.FOUND)
|
||||
@Get("find")
|
||||
async findMany(
|
||||
@Query("limit", new DefaultValuePipe(20), ParseIntPipe) limit: number,
|
||||
@Query("offset", new DefaultValuePipe(0), ParseIntPipe) offset: number,
|
||||
@Query("search", new DefaultValuePipe("")) search: string,
|
||||
) {
|
||||
return this.filesService.search(limit, offset, search);
|
||||
}
|
||||
|
||||
@HttpCode(HttpStatus.CREATED)
|
||||
@UseGuards(AdminGuard)
|
||||
@Post("types/new")
|
||||
async newType(@Body() body: CreateFileTypeDto) {
|
||||
return await this.filesService.createFileType(body.name, body.mime);
|
||||
}
|
||||
@HttpCode(HttpStatus.FOUND)
|
||||
@Get("types")
|
||||
async getTypes() {
|
||||
console.log("Performing request");
|
||||
return await this.filesService.getAllFilesTypes();
|
||||
}
|
||||
|
||||
@HttpCode(HttpStatus.ACCEPTED)
|
||||
@UseGuards(AdminGuard)
|
||||
@Delete("types/:typeId")
|
||||
async delType(@Param(":typeId", ParseUUIDPipe) typeId: string) {
|
||||
return await this.filesService.removeFileType(typeId)
|
||||
}
|
||||
@HttpCode(HttpStatus.CREATED)
|
||||
@UseGuards(AdminGuard)
|
||||
@Post("types/new")
|
||||
async newType(@Body() body: CreateFileTypeDto) {
|
||||
return await this.filesService.createFileType(body.name, body.mime);
|
||||
}
|
||||
|
||||
@HttpCode(HttpStatus.FOUND)
|
||||
@Get(":fileId")
|
||||
async getFile(@Param("fileId") fileId: string) {
|
||||
return await this.filesService.get(fileId);
|
||||
}
|
||||
@HttpCode(HttpStatus.ACCEPTED)
|
||||
@UseGuards(AdminGuard)
|
||||
@Delete("types/:typeId")
|
||||
async delType(@Param(":typeId", ParseUUIDPipe) typeId: string) {
|
||||
return await this.filesService.removeFileType(typeId);
|
||||
}
|
||||
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@UseGuards(AdminGuard)
|
||||
@Delete(":fileId")
|
||||
async deleteFile(@Param("fileId", ParseUUIDPipe) fileId: string) {
|
||||
return await this.filesService.deleteFile(fileId);
|
||||
}
|
||||
@HttpCode(HttpStatus.FOUND)
|
||||
@Get(":fileId")
|
||||
async getFile(@Param("fileId") fileId: string) {
|
||||
return await this.filesService.get(fileId);
|
||||
}
|
||||
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@UseGuards(AdminGuard)
|
||||
@Delete(":fileId")
|
||||
async deleteFile(@Param("fileId", ParseUUIDPipe) fileId: string) {
|
||||
return await this.filesService.deleteFile(fileId);
|
||||
}
|
||||
}
|
||||
|
@ -195,7 +195,7 @@ export class FilesService {
|
||||
.where(eq(FilesGroupTable.uuid, _group))
|
||||
.prepare("checkGroupExists")
|
||||
.execute();
|
||||
|
||||
if (!_group) console.log("No group to link with the file.");
|
||||
if (_group && groupExists.length === 0) {
|
||||
throw new NotFoundException(`Group with ID "${_group}" not found`);
|
||||
}
|
||||
@ -203,7 +203,7 @@ export class FilesService {
|
||||
const saveResult = await this.storage.new(
|
||||
data.get("fileName") as string,
|
||||
file,
|
||||
_machineIds,
|
||||
machinesIds,
|
||||
Boolean(data.get("isDocumentation")),
|
||||
);
|
||||
console.log(saveResult);
|
||||
@ -212,7 +212,7 @@ export class FilesService {
|
||||
.select()
|
||||
.from(FilesTypesTable)
|
||||
.where(eq(FilesTypesTable.mime, saveResult.fileType.mime));
|
||||
|
||||
console.log(mimeId);
|
||||
const inserted = await this.database
|
||||
.use()
|
||||
.insert(FilesTable)
|
||||
@ -227,7 +227,9 @@ export class FilesService {
|
||||
uploadedBy: data.get("uploadedBy") as string,
|
||||
})
|
||||
.returning();
|
||||
if (groupExists[0].uuid) {
|
||||
console.log(inserted);
|
||||
if (_group) {
|
||||
console.log("Adding group ip to file..");
|
||||
await this.database
|
||||
.use()
|
||||
.update(FilesTable)
|
||||
@ -238,7 +240,7 @@ export class FilesService {
|
||||
.execute();
|
||||
}
|
||||
|
||||
console.log(inserted);
|
||||
console.log("File insertion done");
|
||||
|
||||
for (const machineId of machinesIds) {
|
||||
console.log(
|
||||
@ -299,7 +301,7 @@ export class FilesService {
|
||||
.from(FilesTypesTable)
|
||||
.prepare("getAllFilesTypes")
|
||||
.execute();
|
||||
console.log(result)
|
||||
console.log(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
import * as console from "node:console";
|
||||
import * as crypto from "node:crypto";
|
||||
import { readFile, rm, writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
@ -43,13 +42,15 @@ export class StorageService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current MIME type and file size meet the specified conditions.
|
||||
* @param {Array<string>} machineIds - The IDs of the associated machines.
|
||||
* @param {Buffer} file - The file to check.
|
||||
* @return {Promise<boolean>} - A Promise that resolves to true if the conditions are met, false otherwise.
|
||||
* Checks the conditions for the provided file and machine IDs.
|
||||
*
|
||||
* @param {Set<string>} machinesIds - A set containing machine identifiers.
|
||||
* @param {Buffer} file - The file buffer that needs to be checked.
|
||||
* @return {Promise<boolean>} Returns a promise that resolves to true if the conditions are met, otherwise it throws an exception.
|
||||
* @throws {BadRequestException} If the file size exceeds the allowed maximum size or the file MIME type is not allowed.
|
||||
*/
|
||||
private async checkConditions(
|
||||
machineIds: Array<string>,
|
||||
machinesIds: Set<string>,
|
||||
file: Buffer,
|
||||
): Promise<boolean> {
|
||||
/**
|
||||
@ -65,6 +66,7 @@ export class StorageService {
|
||||
): boolean {
|
||||
let notFoundCount = 0;
|
||||
for (const mimesForMachine of mimesForMachines) {
|
||||
console.log(mimesForMachine);
|
||||
const [key, set] = mimesForMachine;
|
||||
if (!set.has(currentMime)) {
|
||||
notFoundCount++;
|
||||
@ -82,10 +84,12 @@ export class StorageService {
|
||||
string,
|
||||
Set<string>
|
||||
>();
|
||||
const mimeSet = new Set(_mimes);
|
||||
// Fetching MIMEs for the associated machines
|
||||
for (const machineId of machineIds) {
|
||||
for (const machineId of machinesIds) {
|
||||
console.debug(`Fetching mimeTypes for machine : ${machineId}`);
|
||||
// Get MIMEs associated to a machine
|
||||
/*
|
||||
const allowedMimeId = this.dbService
|
||||
.use()
|
||||
.select()
|
||||
@ -102,18 +106,31 @@ export class StorageService {
|
||||
.leftJoin(
|
||||
allowedMimeId,
|
||||
eq(FilesTypesTable.id, allowedMimeId.fileTypeId),
|
||||
);*/
|
||||
|
||||
const _allowedMime = await this.dbService
|
||||
.use()
|
||||
.select()
|
||||
.from(FilesTypeForMachine)
|
||||
.where(eq(FilesTypeForMachine.machineId, machineId))
|
||||
.leftJoin(
|
||||
FilesTypesTable,
|
||||
eq(FilesTypesTable.id, FilesTypeForMachine.fileTypeId),
|
||||
);
|
||||
console.log(_allowedMime);
|
||||
console.debug(`Total : ${_allowedMime.length}`);
|
||||
// Append each MIME of a machine
|
||||
const tempSet = new Set<string>();
|
||||
for (const allowedMimeElement of _allowedMime) {
|
||||
tempSet.add(allowedMimeElement.slug);
|
||||
console.debug(
|
||||
`Adding ${allowedMimeElement.f_types.mime} for verification..`,
|
||||
);
|
||||
tempSet.add(allowedMimeElement.f_types.mime);
|
||||
mimeSet.add(allowedMimeElement.f_types.mime);
|
||||
}
|
||||
machinesMap.set(machineId, tempSet);
|
||||
tempSet.clear();
|
||||
}
|
||||
//Store the MIMEs without duplicate
|
||||
const mimeSet = new Set(_mimes);
|
||||
console.debug(`Indexed ${mimeSet.size} unique mimeTypes`);
|
||||
|
||||
//check file size is less than 2mb
|
||||
@ -236,7 +253,7 @@ export class StorageService {
|
||||
public async new(
|
||||
fileDisplayName: string,
|
||||
file: Buffer,
|
||||
machinesId: Array<string>,
|
||||
machinesId: Set<string>,
|
||||
isDocumentation?: boolean,
|
||||
): Promise<IFileInformation> {
|
||||
try {
|
||||
@ -246,7 +263,7 @@ export class StorageService {
|
||||
isDocumentation,
|
||||
);
|
||||
console.log(
|
||||
`Trying to append a new file : "${info.fileDisplayName}"...\n > Checksum SHA-256 : ${info.fileChecksum}\n > Size : ${info.fileSize / (1024 * 1024)}Mio\n > File format : ${info.fileType.mime}\n`,
|
||||
`Trying to append a new file : "${info.fileDisplayName}"...\n > Checksum SHA-256 : ${info.fileChecksum}\n > Size : ${(info.fileSize / (1024 * 1024)).toFixed(6)} Mio\n > File format : ${info.fileType.mime}\n`,
|
||||
);
|
||||
const condition = await this.checkConditions(machinesId, file);
|
||||
if (!condition) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user