/** * @swagger * /api/file/generatepdf: * post: * tags: [Azure Storage] * summary: Phase 2 * description: Create reps pdf from text field * consumes: * - application/json * requestBody: * name: PDF * description: PDF content body * required: true * content: * 'application/json': * schema: * type: object * properties: * representationType: * type: string * example: "Questionnaire" * representationQuestion1: * type: string * example: "question 111111" * representationQuestion2: * type: string * example: "question 232222" * representationCapacity: * type: string * example: "yes" * representationDocuments: * type: array * example: [{}] * pinswg_name: * type: string * example: "2023-8-24-1692882853853--REP_Bond" * containerID: * type: string * example: "cljzkgyev0006f9tl4pk6u171" * appealType: * type: integer * example: 846040000 * incidentID: * type: string * example: "50b533aa-43f1-ec11-aade-00224800be9c" * caseRef: * type: string * example: "CAS-00764-L0Q9W2" * parameters: * - name: container * in: query * required: true * example: cljzkgyev0006f9tl4pk6u171 * schema: * type: string * - name: casefolderID * in: query * required: true * example: CAS-00764-L0Q9W2 * schema: * type: string * - name: hash * in: query * required: true * example: 530b67db992ea277a236790be05b2e49bdd9dd02e6d790cc1c25f96cf39687cb * schema: * type: string * * responses: * 200: * description: Success */ import { createRepPDFBlob } from "../../../actions/azurestorage"; import { hashAPIPath } from "../../../actions/core/hash"; import ReactPDF from "@react-pdf/renderer"; import { EnforcementQuestionnaire_pdf } from "../../../components/pdftemplates/enforcement_pdf"; import { lpaQuestionnaire_pdf } from "../../../components/pdftemplates/lpaQuestionnaire_pdf"; import { finalComments_pdf } from "../../../components/pdftemplates/finalComments_pdf"; import { statement_pdf } from "../../../components/pdftemplates/statement_pdf"; import { writtenStatement_pdf } from "../../../components/pdftemplates/writtenStatement_pdf"; import { other_pdf } from "../../../components/pdftemplates/other_pdf"; import { consoleLogger } from "../../../actions/core/logger"; import { respondError, respondSuccess } from "../middleware/apiResponse"; import { getServerSession } from "next-auth/next"; import { authOptions } from "../auth/[...nextauth]"; //const ApiProxy = nextConnect(); // ApiProxy.use(middleware); // ApiProxy.post(async (req, res) => { const isValidContainer = (value) => typeof value === "string" && value.length >= 3 && value.length <= 63 && /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(value); const isValidDraftFolder = (value) => typeof value === "string" && value.length <= 100 && !value.includes("..") && /^[A-Za-z0-9](?:[A-Za-z0-9/-]*[A-Za-z0-9])?$/.test(value); const forbidden = (res) => respondError(res, { status: 403, code: "FORBIDDEN", message: "Request not permitted" }); export default async function handler(req, res) { const shouldDownload = req.query.download === "true"; const checkHash = req.query.hash; let reqBodyobj; try { reqBodyobj = typeof req.body === "string" ? JSON.parse(req.body) : req.body; } catch (_error) { return respondError(res, { status: 400, code: "INVALID_REQUEST", message: "Invalid request" }); } if ( !reqBodyobj || typeof reqBodyobj !== "object" || Array.isArray(reqBodyobj) ) { return respondError(res, { status: 400, code: "INVALID_REQUEST", message: "Invalid request" }); } const cleanFilesList = (blobList) => { let newblobList = Array.isArray(blobList?.filesList) ? blobList.filesList : []; function removeNullObjects(arr) { if (!Array.isArray(arr) || arr.length === 0) { return arr; } return arr.filter((obj) => obj !== null); } function removeObjectsWithUndefinedKey(arr, key) { if (!Array.isArray(arr) || arr.length === 0) { return arr; } return arr.filter((obj) => obj[key] !== undefined); } function removeEmptyObjects(arr) { if (!Array.isArray(arr) || arr.length === 0) { return arr; } return arr.filter( (obj) => obj && typeof obj === "object" && Object.keys(obj).length > 0 ); } newblobList = removeEmptyObjects(newblobList); newblobList = removeObjectsWithUndefinedKey(newblobList, "name"); newblobList = removeNullObjects(newblobList); Object.assign(blobList, { "filesList": newblobList }); return blobList; }; reqBodyobj = Object.prototype.hasOwnProperty.call( reqBodyobj || {}, "filesList" ) ? cleanFilesList(reqBodyobj) : reqBodyobj; // console.log( // "//////////////////////\nreqBodyobj" + // req + // "\n//////////////////////\n" // ); // console.log( // "//////////////////////\nreqBodyobj" + // JSON.stringify(req.body) + // "\n//////////////////////\n" // ); const containerID = reqBodyobj.containerID; const caseRef = reqBodyobj.ticketnumber || reqBodyobj.caseRef; //console.log("there are files:", Object.keys(req.files).length); let checkquerypath = "/api/file/generatepdf"; if (shouldDownload) { checkquerypath += "?download=true"; } if ( typeof containerID === "undefined" || String(containerID).length === 0 || typeof caseRef === "undefined" || String(caseRef).length === 0 ) { return respondError(res, { status: 400, code: "MISSING_REQUIRED_QUERY", message: "containerID and case reference are required" }); } if ( !isValidContainer(containerID) || !isValidDraftFolder(caseRef) || ["ticketnumber", "caseRef"].some( (key) => Object.prototype.hasOwnProperty.call(reqBodyobj, key) && !isValidDraftFolder(reqBodyobj[key]) ) || (typeof req.query.download !== "undefined" && typeof req.query.download !== "string") || [ "container", "containerID", "casefolderID", "caseRef", "ticketnumber" ].some((key) => Object.prototype.hasOwnProperty.call(req.query, key)) ) { return respondError(res, { status: 400, code: "INVALID_REQUEST", message: "Invalid request" }); } const session = await getServerSession(req, res, authOptions(req, res)); if ( typeof session?.user?.id !== "string" || session.user.id.length === 0 || session.user.id !== containerID ) { return forbidden(res); } if (typeof checkHash !== "string" || checkHash.length === 0) { return respondError(res, { status: 400, code: "HASH_REQUIRED", message: "hash is required" }); } if ( hashAPIPath(checkquerypath) != (checkquerypath.indexOf("?") > -1 ? "&hash=" : "?hash=") + checkHash ) { return respondError(res, { status: 400, code: "INVALID_HASH", message: "Invalid hash" }); } //console.log("-------", checkHash); //console.log(hashAPIPath(checkquerypath) == "?hash=" + checkHash); //console.log(casefolderID, caseRef); // Create Document Component const MyDocument = (values) => { switch (values.docProps.representationType) { case "Questionnaire": switch (values.docProps.appealType) { case 846040005: case 846040006: case 846040007: return EnforcementQuestionnaire_pdf( values, values.docProps.locale ); default: return lpaQuestionnaire_pdf( values, values.docProps.locale ); } return lpaQuestionnaire_pdf(values, values.docProps.locale); break; case "Final comments": return finalComments_pdf(values, values.docProps.locale); break; case "Statement": return statement_pdf(values, values.docProps.locale); break; case "Written statement": return writtenStatement_pdf(values, values.docProps.locale); break; case "Impact": return statement_pdf(values, values.docProps.locale); break; case "Other": return other_pdf(values, values.docProps.locale); break; default: return other_pdf(values, values.docProps.locale); } }; //console.log( // "///////////////////////////////////\n file created: \n" + // process.cwd() + // `tmp/${reqBodyobj.repfile_name}.pdf` + // "\n folder:" + // process.cwd() + // "\n/////////////////////////" // ); // umcomment to render pdf locally // ReactPDF.render( // , // process.cwd() + `/tmp/${reqBodyobj.repfile_name}.pdf` // ); const streamToBuffer = async (readableStream) => { return new Promise((resolve, reject) => { const chunks = []; readableStream.on("data", (chunk) => { chunks.push( Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk) ); }); readableStream.on("end", () => resolve(Buffer.concat(chunks))); readableStream.on("error", reject); }); }; try { const renderedPDFStream = await ReactPDF.renderToStream( MyDocument({ docProps: reqBodyobj }) ); const renderedPDFBuffer = await streamToBuffer(renderedPDFStream); const data = await createRepPDFBlob( renderedPDFBuffer, containerID, caseRef, reqBodyobj.repfile_name ); if (shouldDownload) { const filename = `${reqBodyobj.repfile_name || "questionnaire"}.pdf`; res.setHeader("Content-Type", "application/pdf"); res.setHeader( "Content-Disposition", `attachment; filename="${filename}"` ); return res.status(200).send(renderedPDFBuffer); } return respondSuccess(res, { status: "success", data: data, path: `${caseRef}/${reqBodyobj.repfile_name}/files/${reqBodyobj.repfile_name}.pdf` }); } catch (error) { consoleLogger(error); return respondError(res, { status: 400, code: "GENERATE_PDF_FAILED", message: "Failed to generate PDF" }); } }