add filesNotaryController download route

This commit is contained in:
Max S 2024-09-10 18:11:10 +02:00
parent 41efb43543
commit 5bd5e096ca
8 changed files with 275 additions and 60 deletions

View File

@ -238,9 +238,7 @@ export default class CustomersController extends ApiController {
const documentEntities : Documents[] = [];
//For each document uid, use DocumentsService.getByUid to get the document entity and add it to the documents array
for (const documentUid of documentsUid) {
console.log("documentUid", documentUid);
const documentEntity = await this.documentsService.getByUid(documentUid, { document_type : true, folder : true });
console.log("documentEntity", documentEntity);
if (!documentEntity) {
this.httpBadRequest(response, "Document not found");
@ -250,7 +248,6 @@ export default class CustomersController extends ApiController {
}
const customerEntity = await this.customersService.getByUid(uid, { contact: true, office : true });
console.log("customerEntity", customerEntity);
if (!customerEntity) {
@ -260,13 +257,11 @@ export default class CustomersController extends ApiController {
//Hydrate ressource with prisma entity
const customer = Customer.hydrate<Customer>(customerEntity, { strategy: "excludeAll" });
console.log("customer", customer);
// Call service to send reminder with documents
const reminder = await this.customersService.sendDocumentsReminder(customer, documentEntities);
console.log("Reminder sent", reminder);
// Success

View File

@ -1,16 +1,15 @@
import { Response, Request } from "express";
import { Controller, Delete, Get, Post } from "@ControllerPattern/index";
import ApiController from "@Common/system/controller-pattern/ApiController";
import { Service } from "typedi";
import DocumentsNotaryService from "@Services/notary/DocumentsNotaryService/DocumentsNotaryService";
import { DocumentsNotary, Prisma } from "@prisma/client";
import { DocumentNotary, FileNotary } from "le-coffre-resources/dist/Notary";
import authHandler from "@App/middlewares/AuthHandler";
import OfficeFoldersService from "@Services/notary/OfficeFoldersService/OfficeFoldersService";
import ApiController from "@Common/system/controller-pattern/ApiController";
import { Controller, Delete, Get, Post } from "@ControllerPattern/index";
import { DocumentsNotary, Prisma } from "@prisma/client";
import CustomersService from "@Services/admin/CustomersService/CustomersService";
import FilesNotaryService from "@Services/common/FilesNotaryService/FilesService";
import DocumentsNotaryService from "@Services/notary/DocumentsNotaryService/DocumentsNotaryService";
import OfficeFoldersService from "@Services/notary/OfficeFoldersService/OfficeFoldersService";
import UsersService from "@Services/notary/UsersService/UsersService";
import FilesService from "@Services/common/FilesService/FilesService";
// import NotificationBuilder from "@Common/notifications/NotificationBuilder";
import { Request, Response } from "express";
import { DocumentNotary, FileNotary } from "le-coffre-resources/dist/Notary";
import { Service } from "typedi";
@Controller()
@Service()
@ -20,7 +19,7 @@ export default class DocumentsNotaryController extends ApiController {
private officeFoldersService: OfficeFoldersService,
private customerService: CustomersService,
private userService: UsersService,
private filesService: FilesService,
private filesNotaryService: FilesNotaryService,
) {
super();
}
@ -63,17 +62,13 @@ export default class DocumentsNotaryController extends ApiController {
@Post("/api/v1/notary/documents_notary", [authHandler])
protected async post(req: Request, response: Response) {
try {
console.log("req.file", req.file);
if(!req.file) return;
if (!req.file) return;
const customer = await this.customerService.getByUid(req.body.customerUid);
if (!customer) return;
console.log("customer", customer);
const folder = await this.officeFoldersService.getByUid(req.body.folderUid);
if (!folder) return;
console.log("folder", folder);
const user = await this.userService.getByUid(req.body.user.userId);
if (!user) return;
@ -82,20 +77,19 @@ export default class DocumentsNotaryController extends ApiController {
customer: customer,
folder: folder,
depositor: user,
});
});
const documentNotaryEntityCreated = await this.documentsNotaryService.create(documentNotaryEntity);
console.log("documentNotaryEntityCreated", documentNotaryEntityCreated);
const query = JSON.stringify({ document: { uid: documentNotaryEntityCreated.uid } });
const fileEntity = FileNotary.hydrate<FileNotary>(JSON.parse(query));
const fileEntityCreated = await this.filesService.createFileNotary(fileEntity, req.file!);
if(!fileEntityCreated) {
const fileEntityCreated = await this.filesNotaryService.create(fileEntity, req.file!);
if (!fileEntityCreated) {
this.httpBadRequest(response, "File could not be created");
return;
};
}
const documentNotary = await this.documentsNotaryService.getByUid(documentNotaryEntityCreated.uid);

View File

@ -27,14 +27,14 @@ export default class FilesController extends ApiController {
let query: Prisma.FilesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if(query.where?.uid) {
if (query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId } ;
if(!query.where) query.where = { document: { folder: {office: officeWhereInput}}};
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId };
if (!query.where) query.where = { document: { folder: { office: officeWhereInput } } };
query.where.document!.folder!.office = officeWhereInput;
//call service to get prisma entity
const fileEntities = await this.filesService.get(query);

View File

@ -0,0 +1,109 @@
import authHandler from "@App/middlewares/AuthHandler";
import FilesNotaryHandler from "@App/middlewares/OfficeMembershipHandlers/FilesNotaryHandler";
import ApiController from "@Common/system/controller-pattern/ApiController";
import { Controller, Get } from "@ControllerPattern/index";
import { Prisma } from "@prisma/client";
import FilesNotaryService from "@Services/common/FilesNotaryService/FilesService";
import { Request, Response } from "express";
import { File } from "le-coffre-resources/dist/Notary";
import { Service } from "typedi";
@Controller()
@Service()
export default class FilesNotaryController extends ApiController {
constructor(private filesNotaryService: FilesNotaryService) {
super();
}
/**
* @description Get all Files
* @returns File[] list of Files
*/
@Get("/api/v1/notary/files-notary", [authHandler])
protected async get(req: Request, response: Response) {
try {
//get query
let query: Prisma.FilesFindManyArgs = {};
if (req.query["q"]) {
query = JSON.parse(req.query["q"] as string);
if (query.where?.uid) {
this.httpBadRequest(response, "You can't filter by uid");
return;
}
}
const officeId: string = req.body.user.office_Id;
const officeWhereInput: Prisma.OfficesWhereInput = { uid: officeId };
if (!query.where) query.where = { document: { folder: { office: officeWhereInput } } };
query.where.document!.folder!.office = officeWhereInput;
//call service to get prisma entity
const fileEntities = await this.filesNotaryService.get(query);
//Hydrate ressource with prisma entity
const files = File.hydrateArray<File>(fileEntities, { strategy: "excludeAll" });
//success
this.httpSuccess(response, files);
} catch (error) {
this.httpBadRequest(response, error);
return;
}
}
/**
* @description Get a specific File by uid
*/
@Get("/api/v1/notary/files-notary/download/:uid", [authHandler, FilesNotaryHandler])
protected async download(req: Request, response: Response) {
const uid = req.params["uid"];
if (!uid) {
this.httpBadRequest(response, "uid not found");
return;
}
try {
const fileInfo = await this.filesNotaryService.download(uid);
if (!fileInfo) {
this.httpNotFoundRequest(response, "file not found");
return;
}
response.setHeader("Content-Type", fileInfo.file.mimetype);
response.setHeader("Content-Disposition", `inline; filename=${encodeURIComponent(fileInfo.file.file_name)}`);
this.httpSuccess(response, fileInfo.buffer);
} catch (error) {
this.httpInternalError(response, error);
return;
}
}
/**
* @description Get a specific File by uid
*/
@Get("/api/v1/notary/files-notary/:uid", [authHandler, FilesNotaryHandler])
protected async getOneByUid(req: Request, response: Response) {
try {
const uid = req.params["uid"];
if (!uid) {
this.httpBadRequest(response, "No uid provided");
return;
}
const fileEntity = await this.filesNotaryService.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.httpInternalError(response, error);
return;
}
}
}

View File

@ -57,6 +57,7 @@ import NotesController from "./api/customer/NotesController";
import MailchimpController from "./api/notary/MailchimpController";
import DocumentsReminderController from "./api/notary/DocumentsReminderController";
import DocumentsNotaryController from "./api/notary/DocumentsNotaryController";
import FilesNotaryController from "./api/notary/FilesNotaryController";
/**
* @description This allow to declare all controllers used in the application
@ -120,7 +121,8 @@ export default {
Container.get(RulesGroupsController);
Container.get(NotesController);
Container.get(MailchimpController);
Container.get(DocumentsReminderController)
Container.get(DocumentsNotaryController)
Container.get(DocumentsReminderController);
Container.get(DocumentsNotaryController);
Container.get(FilesNotaryController);
},
};

View File

@ -0,0 +1,48 @@
import HttpCodes from "@Common/system/controller-pattern/HttpCodes";
import FilesNotaryService from "@Services/common/FilesNotaryService/FilesService";
import DocumentsNotaryService from "@Services/notary/DocumentsNotaryService/DocumentsNotaryService";
import { NextFunction, Request, Response } from "express";
import Container from "typedi";
export default async function FilesNotaryHandler(req: Request, response: Response, next: NextFunction) {
try {
const officeId = req.body.user.office_Id;
let uid = req.path && req.path.split("/")[5];
const document = req.body.document;
if (document) {
const documentService = Container.get(DocumentsNotaryService);
const documentWithOffice = await documentService.getByUidWithOffice(document.uid!);
if (!documentWithOffice) {
response.status(HttpCodes.NOT_FOUND).send("Document not found");
return;
}
if (documentWithOffice.folder.office?.uid != officeId) {
response.status(HttpCodes.UNAUTHORIZED).send("Unauthorized with this office");
return;
}
}
if (uid === "download") uid = req.path && req.path.split("/")[6];
if (uid) {
const fileService = Container.get(FilesNotaryService);
const file = await fileService.getByUidWithOffice(uid!);
if (!file) {
response.status(HttpCodes.NOT_FOUND).send("File not found");
return;
}
if (file.document_notary.folder.office.uid != officeId) {
response.status(HttpCodes.UNAUTHORIZED).send("Unauthorized with this office");
return;
}
}
next();
} catch (error) {
console.error(error);
response.status(HttpCodes.INTERNAL_ERROR).send("Internal server error");
return;
}
}

View File

@ -0,0 +1,90 @@
import { BackendVariables } from "@Common/config/variables/Variables";
import { Prisma } from "@prisma/client";
import FilesNotaryRepository from "@Repositories/FilesNotaryRepository";
import FilesRepository from "@Repositories/FilesRepository";
import BaseService from "@Services/BaseService";
import { FileNotary } from "le-coffre-resources/dist/Notary";
import { Readable } from "stream";
import { Service } from "typedi";
import { v4 } from "uuid";
import CryptoService from "../CryptoService/CryptoService";
import IpfsService from "../IpfsService/IpfsService";
@Service()
export default class FilesNotaryService extends BaseService {
constructor(
private filesRepository: FilesRepository,
private ipfsService: IpfsService,
private variables: BackendVariables,
private cryptoService: CryptoService,
private filesNotaryRepository: FilesNotaryRepository,
) {
super();
}
/**
* @description : Get all files
* @throws {Error} If files cannot be ge
*/
public async get(query: Prisma.FilesFindManyArgs) {
return this.filesRepository.findMany(query);
}
/**
* @description : Get a file by uid
* @throws {Error} If project cannot be created
*/
public async getByUid(uid: string) {
return this.filesNotaryRepository.findOneByUid(uid);
}
/**
* @description : Get a file by uid with office
* @throws {Error} If project cannot be created
*/
public async getByUidWithOffice(uid: string) {
return this.filesNotaryRepository.findOneByUidWithOffice(uid);
}
/**
* @description : Get a file by uid with document
* @throws {Error} If project cannot be created
*/
public async getByUidWithDocument(uid: string) {
return this.filesNotaryRepository.findOneByUidWithDocument(uid);
}
/**
* @description : view a file
* @throws {Error} If file cannot be deleted
*/
public async download(uid: string) {
const file = await this.filesNotaryRepository.findOneByUid(uid);
if (!file?.uid) return null;
const fileResult = await fetch(file.file_path.concat("?pinataGatewayToken=").concat(this.variables.PINATA_GATEWAY_TOKEN));
const fileArrayBuffer = await fileResult.arrayBuffer();
return { file: file, buffer: await this.cryptoService.decrypt(Buffer.from(fileArrayBuffer), file.uid) };
}
/**
* @description : Create a new file
* @throws {Error} If file cannot be created
*/
public async create(file: FileNotary, fileData: Express.Multer.File) {
const key = v4();
const encryptedFile = await this.cryptoService.encrypt(fileData.buffer, key);
const hash = await this.cryptoService.getHash(fileData.buffer);
const upload = await this.ipfsService.pinFile(Readable.from(encryptedFile), fileData.originalname);
let fileToCreate: FileNotary = file;
fileToCreate.file_name = fileData.originalname;
fileToCreate.file_path = this.variables.PINATA_GATEWAY.concat(upload.IpfsHash);
fileToCreate.mimetype = fileData.mimetype;
fileToCreate.size = fileData.size;
fileToCreate.hash = hash;
fileToCreate.archived_at = null;
return this.filesNotaryRepository.create(fileToCreate, key);
}
}

View File

@ -1,15 +1,14 @@
import { BackendVariables } from "@Common/config/variables/Variables";
import { Files, Prisma } from "@prisma/client";
import FilesRepository from "@Repositories/FilesRepository";
import BaseService from "@Services/BaseService";
import { Service } from "typedi";
import { File } from "le-coffre-resources/dist/SuperAdmin";
import { Readable } from "stream";
import { Service } from "typedi";
import { v4 } from "uuid";
import CryptoService from "../CryptoService/CryptoService";
import IpfsService from "../IpfsService/IpfsService";
import { BackendVariables } from "@Common/config/variables/Variables";
import { Readable } from "stream";
import { v4 } from "uuid";
import { Files, Prisma } from "@prisma/client";
import { FileNotary } from "le-coffre-resources/dist/Notary";
import FilesNotaryRepository from "@Repositories/FilesNotaryRepository";
@Service()
export default class FilesService extends BaseService {
@ -18,7 +17,6 @@ export default class FilesService extends BaseService {
private ipfsService: IpfsService,
private variables: BackendVariables,
private cryptoService: CryptoService,
private filesNotaryRepository: FilesNotaryRepository
) {
super();
}
@ -88,27 +86,6 @@ export default class FilesService extends BaseService {
return this.filesRepository.create(fileToCreate, key);
}
/**
* @description : Create a new file
* @throws {Error} If file cannot be created
*/
public async createFileNotary(file: FileNotary, fileData: Express.Multer.File) {
const key = v4();
const encryptedFile = await this.cryptoService.encrypt(fileData.buffer, key);
const hash = await this.cryptoService.getHash(fileData.buffer);
const upload = await this.ipfsService.pinFile(Readable.from(encryptedFile), fileData.originalname);
let fileToCreate: FileNotary = file;
fileToCreate.file_name = fileData.originalname;
fileToCreate.file_path = this.variables.PINATA_GATEWAY.concat(upload.IpfsHash);
fileToCreate.mimetype = fileData.mimetype;
fileToCreate.size = fileData.size;
fileToCreate.hash = hash;
fileToCreate.archived_at = null;
return this.filesNotaryRepository.create(fileToCreate, key);
}
/**
* @description : Modify a new file
* @throws {Error} If file cannot be modified