From fa5cd62bd0ec61483ead11cf943d6d4527f8b5ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFs=20Mansot?= <26844641+devfull@users.noreply.github.com> Date: Fri, 22 Sep 2023 17:57:16 +0200 Subject: [PATCH] add route and service to download the document --- .../notary/OfficeFolderAnchorsController.ts | 46 +++++++++++++++++++ .../common/SecureService/SecureService.ts | 31 ++++++++++++- 2 files changed, 76 insertions(+), 1 deletion(-) diff --git a/src/app/api/notary/OfficeFolderAnchorsController.ts b/src/app/api/notary/OfficeFolderAnchorsController.ts index 423f521b..0a93eb4a 100644 --- a/src/app/api/notary/OfficeFolderAnchorsController.ts +++ b/src/app/api/notary/OfficeFolderAnchorsController.ts @@ -17,6 +17,52 @@ export default class OfficeFoldersController extends ApiController { super(); } + /** + * @description Download a folder anchoring proof document + */ + @Get("/api/v1/notary/anchors/download/:uid", [authHandler, ruleHandler, folderHandler]) + protected async download(req: Request, response: Response) { + try { + const uid = req.params["uid"]; + + if (!uid) { + this.httpBadRequest(response, "No uid provided"); + return; + } + + const query = { + documents: { + include: { + files: true, + }, + }, + }; + + const officeFolderFound = await this.officeFoldersService.getByUid(uid, query); + + if (!officeFolderFound) { + this.httpNotFoundRequest(response, "Office folder not found"); + return; + } + + const officeFolder = OfficeFolder.hydrate(officeFolderFound, { strategy: "excludeAll" }); + const folderHashes = getFolderHashes(officeFolder); + + if (folderHashes.length === 0) { + this.httpNotFoundRequest(response, "No file hash to anchor"); + return; + } + + const sortedHashes = [...folderHashes].sort(); + const buffer = await this.secureService.download(sortedHashes); + + this.httpSuccess(response, buffer); + } catch (error) { + this.httpInternalError(response, error); + return; + } + } + /** * @description Create a new folder anchor */ diff --git a/src/services/common/SecureService/SecureService.ts b/src/services/common/SecureService/SecureService.ts index 6ff422df..37dd961b 100644 --- a/src/services/common/SecureService/SecureService.ts +++ b/src/services/common/SecureService/SecureService.ts @@ -1,10 +1,12 @@ import BaseService from "@Services/BaseService"; import { Service } from "typedi"; import { BackendVariables } from "@Common/config/variables/Variables"; +import AnchoringProofService from "@Services/common/AnchoringProofService/AnchoringProofService"; +import EAnchoringStatus from "le-coffre-resources/dist/Notary/EAnchoringStatus"; @Service() export default class SecureService extends BaseService { - constructor(protected variables: BackendVariables) { + constructor(protected variables: BackendVariables, protected anchoringProofService: AnchoringProofService) { super(); } @@ -56,4 +58,31 @@ export default class SecureService extends BaseService { return await response.json(); } + + /** + * @description : Download the anchoring proof document + * @throws {Error} If transaction is not verified on chain + */ + public async download(hash_sources: string[]) { + const anchor = await this.verify(hash_sources); + + if (anchor.transactions.length === 0) { + throw new Error("No anchor found"); + } + + const transaction = anchor.transactions[0]; + + if (transaction.status !== EAnchoringStatus.VERIFIED_ON_CHAIN) { + throw new Error(`Transaction not verified on chain: ${transaction.status}`); + } + + return this.anchoringProofService.generate({ + rootHash: anchor.root_hash, + txLink: transaction.tx_link, + anchoringTime: new Date(transaction.anchoring_timestamp).toLocaleString("fr-FR", { + timeZone: "Europe/Paris", + timeZoneName: "short", + }), + }); + } }