refacto file upload
This commit is contained in:
parent
6e886fe417
commit
6aefea2711
@ -42,19 +42,28 @@ export default class FilesController extends ApiController {
|
|||||||
/**
|
/**
|
||||||
* @description Get a specific File by uid
|
* @description Get a specific File by uid
|
||||||
*/
|
*/
|
||||||
@Get("/api/v1/super-admin/files/upload/:uid")
|
@Get("/api/v1/super-admin/files/download/:uid")
|
||||||
protected async getFileData(req: Request, response: Response) {
|
protected async download(req: Request, response: Response) {
|
||||||
|
const uid = req.params["uid"];
|
||||||
|
if (!uid) {
|
||||||
|
this.httpBadRequest(response, "uid not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const uid = req.params["uid"];
|
const fileInfo = await this.filesService.download(uid);
|
||||||
if (!uid) {
|
|
||||||
throw new Error("No uid provided");
|
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");
|
||||||
this.httpSuccess(response, file);
|
response.setHeader("Content-Disposition", `inline; filename=${encodeURIComponent(fileInfo.file.file_name)}`);
|
||||||
|
|
||||||
|
this.httpSuccess(response, fileInfo.buffer);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.httpBadRequest(response, error);
|
this.httpInternalError(response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,23 +75,22 @@ export default class FilesController extends ApiController {
|
|||||||
@Post("/api/v1/super-admin/files")
|
@Post("/api/v1/super-admin/files")
|
||||||
protected async post(req: Request, response: Response) {
|
protected async post(req: Request, response: Response) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
//get file
|
//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
|
//init File resource with request body values
|
||||||
const fileEntity = File.hydrate<File>(JSON.parse(req.body["q"]));
|
const fileEntity = File.hydrate<File>(JSON.parse(req.body["q"]));
|
||||||
|
|
||||||
//validate File
|
//validate File
|
||||||
await validateOrReject(fileEntity, { groups: ["createFile"] });
|
await validateOrReject(fileEntity, { groups: ["createFile"] });
|
||||||
|
|
||||||
//call service to get prisma entity
|
//call service to get prisma entity
|
||||||
const prismaEntityCreated = await this.filesService.create(fileEntity, req.file);
|
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";
|
document.document_status = "DEPOSITED";
|
||||||
await this.documentService.update(document.uid!, document);
|
await this.documentService.update(document.uid!, document);
|
||||||
|
|
||||||
//Hydrate ressource with prisma entity
|
//Hydrate ressource with prisma entity
|
||||||
const fileEntityCreated = File.hydrate<File>(prismaEntityCreated, {
|
const fileEntityCreated = File.hydrate<File>(prismaEntityCreated, {
|
||||||
strategy: "excludeAll",
|
strategy: "excludeAll",
|
||||||
@ -135,19 +143,24 @@ export default class FilesController extends ApiController {
|
|||||||
try {
|
try {
|
||||||
const uid = req.params["uid"];
|
const uid = req.params["uid"];
|
||||||
if (!uid) {
|
if (!uid) {
|
||||||
throw new Error("No uid provided");
|
this.httpBadRequest(response, "No uid provided");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//call service to get prisma entity
|
//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
|
//Hydrate ressource with prisma entity
|
||||||
const file = File.hydrate<File>(fileEntity, { strategy: "excludeAll" });
|
const file = File.hydrate<File>(fileEntity, { strategy: "excludeAll" });
|
||||||
|
|
||||||
//success
|
//success
|
||||||
this.httpSuccess(response, file);
|
this.httpSuccess(response, file);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.httpBadRequest(response, error);
|
this.httpInternalError(response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,18 +173,24 @@ export default class FilesController extends ApiController {
|
|||||||
try {
|
try {
|
||||||
const uid = req.params["uid"];
|
const uid = req.params["uid"];
|
||||||
if (!uid) {
|
if (!uid) {
|
||||||
throw new Error("No uid provided");
|
this.httpBadRequest(response, "No uid provided");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileEntity = await this.filesService.getByUid(uid);
|
const fileEntity = await this.filesService.getByUid(uid);
|
||||||
|
|
||||||
|
if (!fileEntity) {
|
||||||
|
this.httpNotFoundRequest(response, "file not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//Hydrate ressource with prisma entity
|
//Hydrate ressource with prisma entity
|
||||||
const file = File.hydrate<File>(fileEntity, { strategy: "excludeAll" });
|
const file = File.hydrate<File>(fileEntity, { strategy: "excludeAll" });
|
||||||
|
|
||||||
//success
|
//success
|
||||||
this.httpSuccess(response, file);
|
this.httpSuccess(response, file);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.httpBadRequest(response, error);
|
this.httpInternalError(response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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({
|
return this.model.update({
|
||||||
where: {
|
where: {
|
||||||
uid: uid,
|
uid: uid,
|
||||||
@ -75,17 +75,12 @@ export default class FilesRepository extends BaseRepository {
|
|||||||
/**
|
/**
|
||||||
* @description : Find unique file
|
* @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({
|
const fileEntity = await this.model.findUnique({
|
||||||
where: {
|
where: {
|
||||||
uid: uid,
|
uid: uid,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!fileEntity) {
|
|
||||||
throw new Error("File not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
return fileEntity;
|
return fileEntity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ export default abstract class BaseController {
|
|||||||
return this.httpResponse(response, HttpCodes.NOT_FOUND, responseData);
|
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);
|
return this.httpResponse(response, HttpCodes.INTERNAL_ERROR, responseData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,10 @@ import bodyParser from "body-parser";
|
|||||||
// import TezosLink from "@Common/databases/TezosLink";
|
// import TezosLink from "@Common/databases/TezosLink";
|
||||||
import errorHandler from "@App/middlewares/ErrorHandler";
|
import errorHandler from "@App/middlewares/ErrorHandler";
|
||||||
import { BackendVariables } from "@Common/config/variables/Variables";
|
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 () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
@ -23,7 +26,7 @@ import fileHandler from "@App/middlewares/FileHandler";
|
|||||||
label,
|
label,
|
||||||
port: parseInt(port),
|
port: parseInt(port),
|
||||||
rootUrl,
|
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,
|
errorHandler,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -39,12 +39,12 @@ export default class FilesService extends BaseService {
|
|||||||
* @description : view a file
|
* @description : view a file
|
||||||
* @throws {Error} If file cannot be deleted
|
* @throws {Error} If file cannot be deleted
|
||||||
*/
|
*/
|
||||||
public async updload(uid: string) {
|
public async download(uid: string) {
|
||||||
const file = await this.filesRepository.findOneByUid(uid);
|
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 fileResult = await fetch(file.file_path);
|
||||||
const fileContent = await fileResult.arrayBuffer();
|
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) {
|
public async create(file: File, fileData: Express.Multer.File) {
|
||||||
const key = v4();
|
const key = v4();
|
||||||
|
fileData.mimetype;
|
||||||
|
fileData.size;
|
||||||
const encryptedFile = await this.cryptoService.encrypt(fileData.buffer, key);
|
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);
|
const upload = await this.ipfsService.pinFile(Readable.from(encryptedFile), fileData.originalname);
|
||||||
file.file_name = fileData.originalname; //encryptedFileName.toString('utf-8')
|
file.file_name = fileData.originalname; //encryptedFileName.toString('utf-8')
|
||||||
file.file_path = this.variables.PINATA_GATEWAY.concat(upload.IpfsHash);
|
file.file_path = this.variables.PINATA_GATEWAY.concat(upload.IpfsHash);
|
||||||
@ -71,18 +72,19 @@ export default class FilesService extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description : Delete a file
|
* @description : Delete a file key and archive
|
||||||
* @throws {Error} If file cannot be deleted
|
* @throws {Error} If file key cannot be deleted or archived
|
||||||
*/
|
*/
|
||||||
public async delete(uid: string) {
|
public async deleteKeyAndArchive(uid: string) {
|
||||||
try {
|
try {
|
||||||
const fileToUnpin = await this.filesRepository.findOneByUid(uid);
|
const fileToUnpin = await this.filesRepository.findOneByUid(uid);
|
||||||
const fileHash = fileToUnpin.file_path.substring(this.variables.PINATA_GATEWAY.length);
|
if(!fileToUnpin) return null;
|
||||||
await this.ipfsService.unpinFile(fileHash);
|
const fileHash = fileToUnpin.file_path.substring(this.variables.PINATA_GATEWAY.length);
|
||||||
|
await this.ipfsService.unpinFile(fileHash);
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.filesRepository.delete(uid);
|
return this.filesRepository.deleteKeyAndArchive(uid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user