Merge branch 'staging' into dev

This commit is contained in:
Maxime Lalo 2023-05-11 22:51:16 +02:00
commit b44f5f5a64
6 changed files with 61 additions and 42 deletions

View File

@ -42,5 +42,5 @@ COPY --from=builder --chown=lecoffreuser leCoffre/src/common/databases ./src/com
USER lecoffreuser
CMD ["npm", "run", "api:start"]
CMD ["npm", "run", "start"]
EXPOSE 3001

View File

@ -42,19 +42,28 @@ export default class FilesController extends ApiController {
/**
* @description Get a specific File by uid
*/
@Get("/api/v1/super-admin/files/upload/:uid")
protected async getFileData(req: Request, response: Response) {
@Get("/api/v1/super-admin/files/download/:uid")
protected async download(req: Request, response: Response) {
const uid = req.params["uid"];
if (!uid) {
this.httpBadRequest(response, "uid not found");
return;
}
try {
const uid = req.params["uid"];
if (!uid) {
throw new Error("No uid provided");
const fileInfo = await this.filesService.download(uid);
if (!fileInfo) {
this.httpNotFoundRequest(response);
return;
}
const file = await this.filesService.updload(uid);
const type = fileInfo.file.file_name.split(".").pop();
if (type?.toLowerCase() === "pdf") response.setHeader("Content-Type", "application/pdf");
response.setHeader("Content-Disposition", `inline; filename=${encodeURIComponent(fileInfo.file.file_name)}`);
this.httpSuccess(response, file);
this.httpSuccess(response, fileInfo.buffer);
} catch (error) {
this.httpBadRequest(response, error);
this.httpInternalError(response);
return;
}
}
@ -66,9 +75,8 @@ export default class FilesController extends ApiController {
@Post("/api/v1/super-admin/files")
protected async post(req: Request, response: Response) {
try {
//get file
if(!req.file) throw new Error('No file provided')
if (!req.file) throw new Error("No file provided");
//init File resource with request body values
const fileEntity = File.hydrate<File>(JSON.parse(req.body["q"]));
@ -79,7 +87,7 @@ export default class FilesController extends ApiController {
//call service to get prisma entity
const prismaEntityCreated = await this.filesService.create(fileEntity, req.file);
const document: Document = await this.documentService.getByUid(fileEntity.document!.uid!)
const document: Document = await this.documentService.getByUid(fileEntity.document!.uid!);
document.document_status = "DEPOSITED";
await this.documentService.update(document.uid!, document);
@ -135,19 +143,24 @@ export default class FilesController extends ApiController {
try {
const uid = req.params["uid"];
if (!uid) {
throw new Error("No uid provided");
this.httpBadRequest(response, "No uid provided");
return;
}
//call service to get prisma entity
const fileEntity: Files = await this.filesService.delete(uid);
const fileEntity = await this.filesService.deleteKeyAndArchive(uid);
if (!fileEntity) {
this.httpNotFoundRequest(response, "file not found");
return;
}
//Hydrate ressource with prisma entity
const file = File.hydrate<File>(fileEntity, { strategy: "excludeAll" });
//success
this.httpSuccess(response, file);
} catch (error) {
this.httpBadRequest(response, error);
this.httpInternalError(response);
return;
}
}
@ -160,18 +173,24 @@ export default class FilesController extends ApiController {
try {
const uid = req.params["uid"];
if (!uid) {
throw new Error("No uid provided");
this.httpBadRequest(response, "No uid provided");
return;
}
const fileEntity = await this.filesService.getByUid(uid);
if (!fileEntity) {
this.httpNotFoundRequest(response, "file not found");
return;
}
//Hydrate ressource with prisma entity
const file = File.hydrate<File>(fileEntity, { strategy: "excludeAll" });
//success
this.httpSuccess(response, file);
} catch (error) {
this.httpBadRequest(response, error);
this.httpInternalError(response);
return;
}
}

View File

@ -58,9 +58,9 @@ export default class FilesRepository extends BaseRepository {
}
/**
* @description : Delete a file
* @description : Delete a file key and archive
*/
public async delete(uid: string): Promise<Files> {
public async deleteKeyAndArchive(uid: string): Promise<Files> {
return this.model.update({
where: {
uid: uid,
@ -75,17 +75,12 @@ export default class FilesRepository extends BaseRepository {
/**
* @description : Find unique file
*/
public async findOneByUid(uid: string): Promise<Files> {
public async findOneByUid(uid: string): Promise<Files | null> {
const fileEntity = await this.model.findUnique({
where: {
uid: uid,
},
});
if (!fileEntity) {
throw new Error("File not found");
}
return fileEntity;
}
}

View File

@ -24,7 +24,7 @@ export default abstract class BaseController {
return this.httpResponse(response, HttpCodes.NOT_FOUND, responseData);
}
protected httpInternaleError(response: Response, responseData: IResponseData = "http Internal Server Error") {
protected httpInternalError(response: Response, responseData: IResponseData = "http Internal Server Error") {
return this.httpResponse(response, HttpCodes.INTERNAL_ERROR, responseData);
}

View File

@ -8,7 +8,10 @@ import bodyParser from "body-parser";
// import TezosLink from "@Common/databases/TezosLink";
import errorHandler from "@App/middlewares/ErrorHandler";
import { BackendVariables } from "@Common/config/variables/Variables";
import fileHandler from "@App/middlewares/FileHandler";
//import fileHandler from "@App/middlewares/FileHandler";
import multer from "multer";
const storage = multer.memoryStorage();
(async () => {
try {
@ -23,7 +26,7 @@ import fileHandler from "@App/middlewares/FileHandler";
label,
port: parseInt(port),
rootUrl,
middlwares: [cors({ origin: "*" }), fileHandler, bodyParser.urlencoded({ extended: true }), bodyParser.json()],
middlwares: [cors({ origin: "*" }), multer({storage:storage}).single('file'), bodyParser.urlencoded({ extended: true }), bodyParser.json()],
errorHandler,
});

View File

@ -39,12 +39,12 @@ export default class FilesService extends BaseService {
* @description : view a file
* @throws {Error} If file cannot be deleted
*/
public async updload(uid: string) {
public async download(uid: string) {
const file = await this.filesRepository.findOneByUid(uid);
if (!file.key) throw new Error("file deleted");
if (!file?.key) return null;
const fileResult = await fetch(file.file_path);
const fileContent = await fileResult.arrayBuffer();
return await this.cryptoService.decrypt(Buffer.from(fileContent), file.key);
return {file: file, buffer: await this.cryptoService.decrypt(Buffer.from(fileContent), file.key)};
}
/**
@ -53,8 +53,9 @@ export default class FilesService extends BaseService {
*/
public async create(file: File, fileData: Express.Multer.File) {
const key = v4();
fileData.mimetype;
fileData.size;
const encryptedFile = await this.cryptoService.encrypt(fileData.buffer, key);
//const encryptedFileName = await this.cryptoService.encrypt(Buffer.from(fileData.originalname, 'utf-8'), key);
const upload = await this.ipfsService.pinFile(Readable.from(encryptedFile), fileData.originalname);
file.file_name = fileData.originalname; //encryptedFileName.toString('utf-8')
file.file_path = this.variables.PINATA_GATEWAY.concat(upload.IpfsHash);
@ -71,18 +72,19 @@ export default class FilesService extends BaseService {
}
/**
* @description : Delete a file
* @throws {Error} If file cannot be deleted
* @description : Delete a file key and archive
* @throws {Error} If file key cannot be deleted or archived
*/
public async delete(uid: string) {
public async deleteKeyAndArchive(uid: string) {
try {
const fileToUnpin = await this.filesRepository.findOneByUid(uid);
const fileHash = fileToUnpin.file_path.substring(this.variables.PINATA_GATEWAY.length);
await this.ipfsService.unpinFile(fileHash);
if(!fileToUnpin) return null;
const fileHash = fileToUnpin.file_path.substring(this.variables.PINATA_GATEWAY.length);
await this.ipfsService.unpinFile(fileHash);
} catch(error) {
console.error(error);
}
return this.filesRepository.delete(uid);
return this.filesRepository.deleteKeyAndArchive(uid);
}
}