Merge branch feature/download-proof-zip
into dev (#150)
This commit is contained in:
commit
f08b258b8e
@ -45,6 +45,7 @@
|
|||||||
"@mailchimp/mailchimp_transactional": "^1.0.50",
|
"@mailchimp/mailchimp_transactional": "^1.0.50",
|
||||||
"@pinata/sdk": "^2.1.0",
|
"@pinata/sdk": "^2.1.0",
|
||||||
"@prisma/client": "^4.11.0",
|
"@prisma/client": "^4.11.0",
|
||||||
|
"adm-zip": "^0.5.10",
|
||||||
"class-transformer": "^0.5.1",
|
"class-transformer": "^0.5.1",
|
||||||
"class-validator": "^0.14.0",
|
"class-validator": "^0.14.0",
|
||||||
"classnames": "^2.3.2",
|
"classnames": "^2.3.2",
|
||||||
@ -71,6 +72,7 @@
|
|||||||
"uuidv4": "^6.2.13"
|
"uuidv4": "^6.2.13"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/adm-zip": "^0.5.3",
|
||||||
"@types/cors": "^2.8.13",
|
"@types/cors": "^2.8.13",
|
||||||
"@types/cron": "^2.0.1",
|
"@types/cron": "^2.0.1",
|
||||||
"@types/express": "^4.17.16",
|
"@types/express": "^4.17.16",
|
||||||
|
@ -3,9 +3,10 @@ import { Controller, Get, Post } from "@ControllerPattern/index";
|
|||||||
import ApiController from "@Common/system/controller-pattern/ApiController";
|
import ApiController from "@Common/system/controller-pattern/ApiController";
|
||||||
import { Service } from "typedi";
|
import { Service } from "typedi";
|
||||||
import { Document, OfficeFolder } from "le-coffre-resources/dist/Notary";
|
import { Document, OfficeFolder } from "le-coffre-resources/dist/Notary";
|
||||||
import { getFolderHashes } from "@Common/optics/notary";
|
import { getFolderHashes, getFolderFilesUid } from "@Common/optics/notary";
|
||||||
import OfficeFoldersService from "@Services/notary/OfficeFoldersService/OfficeFoldersService";
|
import OfficeFoldersService from "@Services/notary/OfficeFoldersService/OfficeFoldersService";
|
||||||
import OfficeFolderAnchorsRepository from "@Repositories/OfficeFolderAnchorsRepository";
|
import OfficeFolderAnchorsRepository from "@Repositories/OfficeFolderAnchorsRepository";
|
||||||
|
import FilesService from "@Services/common/FilesService/FilesService";
|
||||||
import SecureService from "@Services/common/SecureService/SecureService";
|
import SecureService from "@Services/common/SecureService/SecureService";
|
||||||
import authHandler from "@App/middlewares/AuthHandler";
|
import authHandler from "@App/middlewares/AuthHandler";
|
||||||
import ruleHandler from "@App/middlewares/RulesHandler";
|
import ruleHandler from "@App/middlewares/RulesHandler";
|
||||||
@ -14,6 +15,7 @@ import OfficeFolderAnchor from "le-coffre-resources/dist/Notary/OfficeFolderAnch
|
|||||||
import NotificationBuilder from "@Common/notifications/NotificationBuilder";
|
import NotificationBuilder from "@Common/notifications/NotificationBuilder";
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
import OfficeFolderAnchorsService from "@Services/notary/OfficeFolderAnchorsService/OfficeFolderAnchorsService";
|
import OfficeFolderAnchorsService from "@Services/notary/OfficeFolderAnchorsService/OfficeFolderAnchorsService";
|
||||||
|
import Zip from "adm-zip";
|
||||||
|
|
||||||
const hydrateOfficeFolderAnchor = (data: any): OfficeFolderAnchor =>
|
const hydrateOfficeFolderAnchor = (data: any): OfficeFolderAnchor =>
|
||||||
OfficeFolderAnchor.hydrate<OfficeFolderAnchor>(
|
OfficeFolderAnchor.hydrate<OfficeFolderAnchor>(
|
||||||
@ -41,13 +43,14 @@ export default class OfficeFoldersController extends ApiController {
|
|||||||
private officeFolderAnchorsRepository: OfficeFolderAnchorsRepository,
|
private officeFolderAnchorsRepository: OfficeFolderAnchorsRepository,
|
||||||
private officeFolderAnchorsService: OfficeFolderAnchorsService,
|
private officeFolderAnchorsService: OfficeFolderAnchorsService,
|
||||||
private officeFoldersService: OfficeFoldersService,
|
private officeFoldersService: OfficeFoldersService,
|
||||||
|
private filesService: FilesService,
|
||||||
private notificationBuilder: NotificationBuilder,
|
private notificationBuilder: NotificationBuilder,
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description Download a folder anchoring proof document
|
* @description Download a folder anchoring proof document along with all accessible files
|
||||||
*/
|
*/
|
||||||
@Get("/api/v1/notary/anchors/download/:uid", [authHandler, ruleHandler, folderHandler])
|
@Get("/api/v1/notary/anchors/download/:uid", [authHandler, ruleHandler, folderHandler])
|
||||||
protected async download(req: Request, response: Response) {
|
protected async download(req: Request, response: Response) {
|
||||||
@ -76,6 +79,7 @@ export default class OfficeFoldersController extends ApiController {
|
|||||||
|
|
||||||
const officeFolder = OfficeFolder.hydrate<OfficeFolder>(officeFolderFound, { strategy: "excludeAll" });
|
const officeFolder = OfficeFolder.hydrate<OfficeFolder>(officeFolderFound, { strategy: "excludeAll" });
|
||||||
const folderHashes = getFolderHashes(officeFolder);
|
const folderHashes = getFolderHashes(officeFolder);
|
||||||
|
const folderFilesUid = getFolderFilesUid(officeFolder);
|
||||||
|
|
||||||
if (folderHashes.length === 0) {
|
if (folderHashes.length === 0) {
|
||||||
this.httpNotFoundRequest(response, "No file hash to anchor");
|
this.httpNotFoundRequest(response, "No file hash to anchor");
|
||||||
@ -83,10 +87,25 @@ export default class OfficeFoldersController extends ApiController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const sortedHashes = [...folderHashes].sort();
|
const sortedHashes = [...folderHashes].sort();
|
||||||
const buffer = await this.secureService.download(sortedHashes);
|
const anchoringProof = await this.secureService.download(sortedHashes);
|
||||||
|
|
||||||
response.setHeader("Content-Type", "application/pdf");
|
const addFileToZip = (zip: Zip) => (uid: string): Promise<void> =>
|
||||||
this.httpSuccess(response, buffer);
|
(async () => {
|
||||||
|
const data = await this.filesService.download(uid);
|
||||||
|
if (!data?.buffer) return;
|
||||||
|
zip.addFile(`${uid}-${data.file.file_name}`, data.buffer);
|
||||||
|
})()
|
||||||
|
|
||||||
|
const uids: string[] = folderFilesUid.filter((uid): uid is string => uid !== undefined);
|
||||||
|
|
||||||
|
const zip = new Zip();
|
||||||
|
zip.addFile(`${uid}-certificat-de-dépôt.pdf`, anchoringProof);
|
||||||
|
await Promise.allSettled(
|
||||||
|
uids.map(addFileToZip(zip))
|
||||||
|
)
|
||||||
|
|
||||||
|
response.setHeader("Content-Type", "application/zip");
|
||||||
|
this.httpSuccess(response, zip.toBuffer());
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.httpInternalError(response, error);
|
this.httpInternalError(response, error);
|
||||||
return;
|
return;
|
||||||
|
@ -10,6 +10,7 @@ import { Document, File, OfficeFolder } from "le-coffre-resources/dist/Notary";
|
|||||||
export const folderDocumentsLens = Optics.Lens.fromNullableProp<OfficeFolder>()("documents", []);
|
export const folderDocumentsLens = Optics.Lens.fromNullableProp<OfficeFolder>()("documents", []);
|
||||||
export const documentFilesLens = Optics.Lens.fromNullableProp<Document>()("files", []);
|
export const documentFilesLens = Optics.Lens.fromNullableProp<Document>()("files", []);
|
||||||
export const fileHashLens = Optics.Lens.fromProp<File>()("hash");
|
export const fileHashLens = Optics.Lens.fromProp<File>()("hash");
|
||||||
|
export const fileUidLens = Optics.Lens.fromProp<File>()("uid");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Traversals
|
* Traversals
|
||||||
@ -17,13 +18,17 @@ export const fileHashLens = Optics.Lens.fromProp<File>()("hash");
|
|||||||
export const documentsTraversal = Optics.fromTraversable(Array.Traversable)<Document>();
|
export const documentsTraversal = Optics.fromTraversable(Array.Traversable)<Document>();
|
||||||
export const filesTraversal = Optics.fromTraversable(Array.Traversable)<File>();
|
export const filesTraversal = Optics.fromTraversable(Array.Traversable)<File>();
|
||||||
|
|
||||||
export const folderHashesTraversal = folderDocumentsLens
|
export const folderFilesTraversal = folderDocumentsLens
|
||||||
.composeTraversal(documentsTraversal)
|
.composeTraversal(documentsTraversal)
|
||||||
.composeLens(documentFilesLens)
|
.composeLens(documentFilesLens)
|
||||||
.composeTraversal(filesTraversal)
|
.composeTraversal(filesTraversal);
|
||||||
.composeLens(fileHashLens);
|
|
||||||
|
export const folderHashesTraversal = folderFilesTraversal.composeLens(fileHashLens);
|
||||||
|
export const folderFilesUidTraversal = folderFilesTraversal.composeLens(fileUidLens);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Getters
|
* Getters
|
||||||
*/
|
*/
|
||||||
|
export const getFolderFiles = (folder: OfficeFolder) => Traversal.getAll(folder)(folderFilesTraversal);
|
||||||
export const getFolderHashes = (folder: OfficeFolder) => Traversal.getAll(folder)(folderHashesTraversal);
|
export const getFolderHashes = (folder: OfficeFolder) => Traversal.getAll(folder)(folderHashesTraversal);
|
||||||
|
export const getFolderFilesUid = (folder: OfficeFolder) => Traversal.getAll(folder)(folderFilesUidTraversal);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user