diff --git a/apps/dashboard/src/main/java/com/akto/action/ReportAction.java b/apps/dashboard/src/main/java/com/akto/action/ReportAction.java index 6fbfefa72f..6d3b64290b 100644 --- a/apps/dashboard/src/main/java/com/akto/action/ReportAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/ReportAction.java @@ -1,8 +1,7 @@ package com.akto.action; import java.net.URL; -import java.util.HashMap; -import java.util.Map; +import java.util.*; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -13,10 +12,13 @@ import com.akto.dao.testing.sources.TestReportsDao; import com.akto.dto.testing.sources.TestReports; +import com.fasterxml.jackson.databind.ObjectMapper; import com.mongodb.MongoCommandException; import com.mongodb.client.model.Filters; import com.mongodb.client.model.Updates; +import org.apache.commons.lang3.StringUtils; import org.apache.struts2.ServletActionContext; +import org.bson.BsonMaximumSizeExceededException; import org.bson.types.ObjectId; import org.json.JSONObject; @@ -36,7 +38,7 @@ public class ReportAction extends UserAction { private String organizationName; private String reportDate; private String reportUrl; - private String pdf; + private List pdf; private String status; private boolean firstPollRequest; @@ -70,9 +72,13 @@ public String downloadReportPDF() { if(firstPollRequest) { TestReports testReport = TestReportsDao.instance.findOne(Filters.eq("_id", reportUrlIdObj)); - if(testReport != null && (testReport.getPdfReportString() != null && !testReport.getPdfReportString().isEmpty())) { + if(testReport != null && !StringUtils.isEmpty(testReport.getPdfReportString())) { status = "COMPLETED"; - pdf = testReport.getPdfReportString(); + pdf = Arrays.asList(testReport.getPdfReportString()); + return SUCCESS.toUpperCase(); + } else if(testReport != null && (testReport.getPdfReportStringChunks() != null && !testReport.getPdfReportStringChunks().isEmpty())) { + status = "COMPLETED"; + pdf = testReport.getPdfReportStringChunks(); return SUCCESS.toUpperCase(); } } @@ -134,27 +140,40 @@ public String downloadReportPDF() { if (status.equals("COMPLETED")) { loggerMaker.infoAndAddToDb("Pdf download status for report id - " + reportId + " completed. Attaching pdf in response ", LogDb.DASHBOARD); - pdf = node.get("base64PDF").textValue(); + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode base64PDF = node.get("base64PDF"); + if(base64PDF == null) { + status = "ERROR"; + return ERROR.toUpperCase(); + } + pdf = objectMapper.convertValue(base64PDF, List.class); + try { - TestReportsDao.instance.updateOne(Filters.eq("_id", reportUrlIdObj), Updates.set(TestReports.PDF_REPORT_STRING, pdf)); + TestReportsDao.instance.updateOne(Filters.eq("_id", reportUrlIdObj), Updates.set(TestReports.PDF_REPORT_STRING_CHUNKS, pdf)); } catch(Exception e) { loggerMaker.errorAndAddToDb("Error: " + e.getMessage() + ", while updating report binary for reportId: " + reportId, LogDb.DASHBOARD); if (e instanceof MongoCommandException) { MongoCommandException mongoException = (MongoCommandException) e; if (mongoException.getCode() == 17420) { - addActionError("The report is too large to save. Please reduce its size and try again."); + status = "COMPLETED"; + return SUCCESS.toUpperCase(); } else { addActionError("A database error occurred while saving the report. Try again later."); } + } else if(e instanceof BsonMaximumSizeExceededException) { + status = "COMPLETED"; + return SUCCESS.toUpperCase(); } else { addActionError("An error occurred while updating the report in DB. Please try again."); } status = "ERROR"; + return ERROR.toUpperCase(); } } } catch (Exception e) { loggerMaker.errorAndAddToDb(e, "Error while polling pdf download for report id - " + reportId, LogDb.DASHBOARD); status = "ERROR"; + return ERROR.toUpperCase(); } } @@ -193,11 +212,11 @@ public void setReportUrl(String reportUrl) { this.reportUrl = reportUrl; } - public String getPdf() { + public List getPdf() { return pdf; } - public void setPdf(String pdf) { + public void setPdf(List pdf) { this.pdf = pdf; } diff --git a/apps/dashboard/src/main/java/com/akto/action/testing_issues/IssuesAction.java b/apps/dashboard/src/main/java/com/akto/action/testing_issues/IssuesAction.java index 5f76b8195a..91a8e57ff4 100644 --- a/apps/dashboard/src/main/java/com/akto/action/testing_issues/IssuesAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/testing_issues/IssuesAction.java @@ -739,7 +739,7 @@ public String fetchTestingRunResultsSummary() { public String generateTestReport () { try { - TestReports testReport = new TestReports(reportFilterList, Context.now(), "", this.issuesIdsForReport); + TestReports testReport = new TestReports(reportFilterList, Context.now(), "", new ArrayList<>(), this.issuesIdsForReport); InsertOneResult insertTResult = TestReportsDao.instance.insertOne(testReport); this.generatedReportId = insertTResult.getInsertedId().toString(); return SUCCESS.toUpperCase(); diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/vulnerability_report/VulnerabilityReport.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/vulnerability_report/VulnerabilityReport.jsx index fb68a80bfe..af28cd55b8 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/vulnerability_report/VulnerabilityReport.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/vulnerability_report/VulnerabilityReport.jsx @@ -304,7 +304,8 @@ const VulnerabilityReport = () => { else { // Download the PDF try { - const byteCharacters = atob(pdf); + const stringPdf = pdf.join('') + const byteCharacters = atob(stringPdf); const byteNumbers = new Array(byteCharacters.length); for (let i = 0; i < byteCharacters.length; i++) { byteNumbers[i] = byteCharacters.charCodeAt(i); diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/vulnerability_report/styles.css b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/vulnerability_report/styles.css index db8ee5b627..a651907638 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/vulnerability_report/styles.css +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/testing/vulnerability_report/styles.css @@ -13,6 +13,10 @@ margin: auto 5vw; height: auto; } + + .Polaris-Frame-ToastManager { + display: none !important; + } } .report-header-css { diff --git a/libs/dao/src/main/java/com/akto/dto/testing/sources/TestReports.java b/libs/dao/src/main/java/com/akto/dto/testing/sources/TestReports.java index f3e336a5e3..4a54e14861 100644 --- a/libs/dao/src/main/java/com/akto/dto/testing/sources/TestReports.java +++ b/libs/dao/src/main/java/com/akto/dto/testing/sources/TestReports.java @@ -16,15 +16,19 @@ public class TestReports { public static final String PDF_REPORT_STRING = "pdfReportString"; private String pdfReportString; + public static final String PDF_REPORT_STRING_CHUNKS = "pdfReportStringChunks"; + private List pdfReportStringChunks; + public static final String ISSUE_IDS_FOR_REPORT = "issuesIdsForReport"; private List issuesIdsForReport; public TestReports () {} - public TestReports (Map> filtersForReport, int timestamp, String pdfReportString, List issuesIdsForReport){ + public TestReports (Map> filtersForReport, int timestamp, String pdfReportString, List pdfReportStringChunks, List issuesIdsForReport){ this.filtersForReport = filtersForReport; this.timestamp = timestamp; this.pdfReportString = pdfReportString; + this.pdfReportStringChunks = pdfReportStringChunks; this.issuesIdsForReport = issuesIdsForReport; } @@ -60,4 +64,12 @@ public List getIssuesIdsForReport() { public void setIssuesIdsForReport(List issuesIdsForReport) { this.issuesIdsForReport = issuesIdsForReport; } + + public List getPdfReportStringChunks() { + return pdfReportStringChunks; + } + + public void setPdfReportStringChunks(List pdfReportStringChunks) { + this.pdfReportStringChunks = pdfReportStringChunks; + } }